Estoy escribiendo una aplicación Java que necesita usar una aplicación de línea de comando externa usando la biblioteca Apache Commons Exec. La aplicación que necesito ejecutar tiene un tiempo de carga bastante largo, por lo que sería preferible mantener viva una instancia en lugar de crear un proceso nuevo cada vez. La forma en que funciona la aplicación es muy simple. Una vez iniciado, espera una nueva entrada y genera algunos datos como salida, los cuales usan la E/S estándar de la aplicación.Problema al proporcionar entrada múltiple a un comando usando Apache Commons Exec y extraer la salida
Así que la idea sería ejecutar CommandLine, y luego usar PumpStreamHandler con tres flujos separados (salida, error y entrada) y usar esas transmisiones para interactuar con la aplicación. Hasta ahora, he tenido este trabajo en escenarios básicos donde tengo una entrada, una salida y luego la aplicación se apaga. Pero tan pronto como trato de tener una segunda transacción, algo sale mal.
Después de haber creado mi CommandLine, creo mi Ejecutor y poner en marcha este modo:
this.executor = new DefaultExecutor();
PipedOutputStream stdout = new PipedOutputStream();
PipedOutputStream stderr = new PipedOutputStream();
PipedInputStream stdin = new PipedInputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(stdout, stderr, stdin);
this.executor.setStreamHandler(streamHandler);
this.processOutput = new BufferedInputStream(new PipedInputStream(stdout));
this.processError = new BufferedInputStream(new PipedInputStream(stderr));
this.processInput = new BufferedOutputStream(new PipedOutputStream(stdin));
this.resultHandler = new DefaultExecuteResultHandler();
this.executor.execute(cmdLine, resultHandler);
entonces proceder al lanzamiento de tres hilos diferentes, cada uno de manejo de una corriente diferente. También tengo tres SynchronousQueues que manejan entrada y salida (uno usado como entrada para el flujo de entrada, uno para informar al outputQueue que un nuevo comando ha sido lanzado y uno para salida). Por ejemplo, el hilo flujo de entrada tiene el siguiente aspecto:
while (!killThreads) {
String input = inputQueue.take();
processInput.write(input.getBytes());
processInput.flush();
IOQueue.put(input);
}
Si quito el bucle de tiempo y acaba de ejecutar esta vez, todo parece funcionar perfectamente. Obviamente, si intento ejecutarlo de nuevo, PumpStreamHandler lanza una excepción porque se ha accedido por dos hilos diferentes.
El problema aquí es que parece que processInput no se vacía realmente hasta que termina el hilo. Cuando se depura, la aplicación de línea de comandos solo recibe su entrada una vez que termina el hilo, pero nunca la obtiene si se mantiene el ciclo while. He intentado muchas cosas diferentes para que el processInput se descargue pero nada parece funcionar.
¿Alguien ha intentado algo similar antes? ¿Hay algo que me falta? ¡Cualquier ayuda sería muy apreciada!
debe agregar una etiqueta java a su publicación, a los 'ojos' más experimentados en su problema. Buena suerte. – shellter