Domanda

Tutti,

In origine avevo uno script di shell che ha chiamato SQLLoader (gli Oracoli di dati strumento di upload).

Il problema era che SQLLoader richiede una password di testo come input, così ho deciso di creare un'applicazione Java per chiamare SQLLoader internamente passando decriptato password nella stringa di comando.

ad es.

sqlldr user/pass@Serverdb di controllo=../sqlloader.ctl log=sqlloader.i dati di log=mydata.csv

Così con il mio wrapper java è diventato questo nel mio script di shell

java -jar sqlloader.jar sqlloader.ctl mydata.csv

Tuttavia, un nuovo problema si è sviluppato quando SQLLoader lamentato non c'è nessun file da caricare.Dopo qualche testa di graffiare è scoperto che il successivo comando nel mio script di shell sembrava essere in esecuzione durante la mia applicazione java è ancora in esecuzione.Quindi si comportava in modo asincrono.

Il comando successivo fu di spostare il file di input sqlloader stava usando prima che potesse avere la possibilità di usarlo.Così ho messo un comando di sospensione di 20 secondi per dare la mia applicazione java tempo per l'esecuzione.

java -jar sqlloader.jar sqlloader.ctl mydata.csv
echo $?
sleep 20
if [ $? -ne 0 ]
    then
        echo "SQLLoader failed during execution, please check the log : " 
        mv mydata.csv

else
    echo "SQLLoader successfully processed file : "
    mv mydata.csv
fi

Qualcuno sa perché unix è comportarsi in questo modo, non Java eseguire il mio SQLLoader come un altro utente/ thread?

Questo è il mio codice java:

    Runtime Rt;
Process Prc;
    Prc = Rt.exec("sqlldr user/decryptedpass@DBServer control=../sqlloader.ctl log=sqlloader.log data=mydata.csv);
system.exit(0);

Ho controllato la Classe Runtime per nulla essere Asincrono, ma non riuscivo a trovare nulla

http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

Ogni teorie o suggerimenti?

Grazie

È stato utile?

Soluzione

Sì. Se si guarda di nuovo Runtime.exec, specifica che lancerà un nuovo processo nell'ambiente specificato (ad esempio indipendentemente dall'attuale "ambiente" o come lo si mette in modo asincrono). Dovresti usare ProcessBuilder per creare un Processi E poi waitfor quel processo per finire prima di chiamare System.xit - che certamente non è obbligatorio. Qualcosa come questo

public static void main(String[] args) {
    // String command = "/usr/bin/sleep 5";
    List<String> command = new ArrayList<String>();
    command.add("c:/cygwin/bin/sleep");
    command.add("5");
    ProcessBuilder pb = new ProcessBuilder(command);
    BufferedReader is = null;
    try {
        System.out.println("Starting command " + command);
        Process p = pb.start();

        int ret = p.waitFor();
        is = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while ((line = is.readLine()) != null) {
            System.out.println(line);
        }
        if (ret == 0) {
            System.out.println("Command has completed.");
            System.exit(ret);
        } else {
            System.out.println("Command completed with return code " + ret);
            System.exit(ret);
        }
    } catch (Exception e) {
        System.out.println("Caught Exception " + e.getMessage()
                + " running command " + command);
        e.printStackTrace();
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
            }
        }
    }
    System.out.println("COMMAND FAILED");
    System.exit(1);
}

Altri suggerimenti

È necessario attendere il completamento del processo di, si dovrebbe anche leggere tutto l'output (stdout e stderr) dal processo che si sta avviando.

Se si chiama exit() dopo exec(), Java farà - uscita immediatedly.

Ecco un articolo che spiega in fase di Runtime.exec insidie: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4 (considerare anche le altre pagine).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top