ProcessBuilder в Java не выполняет команду «java -jar» - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь выполнить команды Windows (которые мы можем выполнить через командную строку), через Java-код, с помощью Processbuilder и получить ответ.Моя программа прекрасно работает для команд типа 'dir', но не работает для 'java -jar'.Когда я даю 'java -jar C: \ mypath \ filename.jar', он ждет вечно и даже не получает никакого ввода из потока.Можете ли вы помочь с этим?Примечание: это работает нормально, если мы делаем это через командную строку.

public byte[] execute(String command) {
        ProcessBuilder builder = new ProcessBuilder();
        LOG.info("Executing the command {} ...", command);

        builder.command("cmd.exe", "/c", command);

        builder.redirectErrorStream(true);

        try {
            Process process = builder.start();
            StringBuffer outStringBuffer = new StringBuffer();
            StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), x -> {
                outStringBuffer.append(x).append("\n");
            });
            Future<?> future = Executors.newSingleThreadExecutor().submit(streamGobbler);
            future.get(120, TimeUnit.SECONDS);//Waiting for 120 seconds and throwing error with null.
            int exitCode = process.waitFor();// If we skip prev step, waiting for ever for this process.
            System.out.println("ExitCode:"+exitCode);

            // assert exitCode == 0;
            if (exitCode == 0) {
                LOG.info("Command \'{}\' executed. And response:{}", command, outStringBuffer.toString());
                return outStringBuffer.toString().getBytes();
            } else {
                LOG.error("Command \'{}\' executed. And process exited with exitCode:{}. Response stored:{}.", command,
                        exitCode, outStringBuffer.toString());
                return ("Process exited with exitCode" + exitCode).getBytes();
            }

        } catch (IOException | InterruptedException | ExecutionException | TimeoutException e) {
            LOG.error("Error in execution of command:{}. Details of error:{}.{}", command, e.getMessage(), e);
            return ("Error in execution of command:" + command + ". Details of error:" + e.getMessage() + "." + e)
                    .getBytes();
        }
    }


    public class StreamGobbler implements Runnable {
    private InputStream inputStream;
    private Consumer<String> consumer;

    public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
        this.inputStream = inputStream;
        this.consumer = consumer;
    }

    @Override
    public void run() {
        new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumer);
    }
}

1 Ответ

0 голосов
/ 11 октября 2018

Понятно, что обработка Future и процесса - ошибка, если подпроцесс занимает слишком много времени для завершения.Обновлен код для обработки.

try {
                future.get(120, TimeUnit.SECONDS);
            } catch (TimeoutException e) {
                readerTimedOut = true;
                LOG.info("The Reader for the process did not complete till timeout seconds:{}", 120);
            }
int processTimeOutSeconds = 40;
            if (readerTimedOut) {
                processTimeOutSeconds = 0;
            }
            boolean isProcessTerminated = process.waitFor(processTimeOutSeconds, TimeUnit.SECONDS);
...