Pregunta

Todos,

Originalmente tenía un script de shell que llamaba sqlloader (herramienta de carga de datos de oráculos).

El problema era que SQLloader toma una contraseña de texto sin formato como entrada, así que decidí crear una aplicación Java para llamar a SQLloader pasando internamente una contraseña descifrada en la cadena de comando.

p.ej

SQLLDR user/pass@dbserver control = ../sqlloader.ctl log = sqlloader.log data = myData.csv

Entonces, con mi envoltura de Java, se convirtió en esto en mi guión de shell

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

Sin embargo, se desarrolló un nuevo problema cuando SQLloader se quejó de que no había archivo para cargar. Después de un rascado de la cabeza, se descubrió que un comando posterior en mi script de shell parecía estar ejecutándose mientras mi aplicación Java todavía se estaba ejecutando. Por lo tanto, se estaba comportando asincrónicamente.

El siguiente comando fue mover el archivo de entrada que SQLloader estaba usando antes de que pudiera tener la oportunidad de usarlo. Así que puse un comando de sueño en 20 segundos para dar mi tiempo de aplicación Java para ejecutar.

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

¿Alguien sabe por qué Unix se está comportando de esta manera? ¿Java ejecuta mi sqlloader como un usuario/ hilo diferente?

Este es mi código Java:

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

Revisé la clase de tiempo de ejecución para obtener algo sobre que fuera asíncrono pero no pude encontrar nada

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

¿Alguna teoría o sugerencia?

Gracias

¿Fue útil?

Solución

Sí. Si observa RunTime.Exec nuevamente, especifica que lanzará un nuevo proceso en el entorno especificado (por ejemplo, independientemente del "entorno" actual o como lo pone de manera asincrónica). Deberías usar Proceso de proceso para crear un Proceso y luego espera que ese proceso finalice antes de llamar al sistema. Exit, lo que ciertamente no es obligatorio. Algo como esto

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);
}

Otros consejos

Debe esperar la finalización del proceso, también debe leer todo el resultado (stDout y stderr) del proceso que está comenzando.

Si llama a Exit () después de Exec (), Java hará exactamente eso, saldrá inmediatamente.

Aquí hay un artículo que explica el tiempo de ejecución.exec las dificultades: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-taps.html?page=4 (También considere las otras páginas).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top