Sto scrivendo un'applicazione Java che deve utilizzare un'applicazione esterna a riga di comando utilizzando la libreria Apache Commons Exec. L'applicazione che devo eseguire ha un tempo di caricamento abbastanza lungo, quindi sarebbe preferibile mantenere un'istanza attiva invece di creare un nuovo processo ogni volta. Il modo in cui funziona l'applicazione è molto semplice. Una volta avviato, attende alcuni nuovi input e genera alcuni dati come output, entrambi utilizzano l'I/O standard dell'applicazione.Problemi nel fornire più input a un comando utilizzando Apache Commons Exec ed estrazione dell'output
Quindi l'idea sarebbe di eseguire CommandLine e quindi utilizzare PumpStreamHandler con tre flussi separati (output, errore e input) e utilizzare tali flussi per interagire con l'applicazione. Finora, ho avuto questo lavoro in scenari di base in cui ho un input, un output e l'applicazione quindi si spegne. Ma non appena sto provando ad avere una seconda transazione, qualcosa va storto.
dopo aver creato il mio CommandLine, Creo il mio esecutore e lanciarlo in questo 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);
ho quindi procedere al lancio di tre diversi fili, ciascuno di una gestione di un flusso diverso. Ho anche tre SynchronousQueues che gestiscono input e output (uno usato come input per il flusso di input, uno per informare l'outputQueue che è stato lanciato un nuovo comando e uno per l'output). Ad esempio, il filo flusso di input è simile al seguente:
while (!killThreads) {
String input = inputQueue.take();
processInput.write(input.getBytes());
processInput.flush();
IOQueue.put(input);
}
Se rimuovo il ciclo while e proprio eseguo per questa volta, tutto sembra funzionare perfettamente. Ovviamente, se provo ad eseguirlo di nuovo, PumpStreamHandler genera un'eccezione perché è stata letta da due thread differenti.
Il problema qui è che sembra che il processoInput non sia veramente svuotato fino alla fine del thread. Quando viene eseguito il debug, l'applicazione della riga di comando riceve il proprio input solo quando il thread termina, ma non lo ottiene mai se il ciclo while viene mantenuto. Ho provato molte cose diverse per far sì che processInput venisse svuotato, ma nulla sembra funzionare.
Qualcuno ha tentato qualcosa di simile prima? C'è qualcosa che mi manca? Qualsiasi aiuto sarebbe molto apprezzato!
dovresti aggiungere un tag java al tuo post, agli "occhi" più esperti sul tuo problema. In bocca al lupo. – shellter