java 中的 ProcessBuilder 未执行 'java -jar' 命令
ProcessBuilder in java not executing the 'java -jar' command
我正在尝试执行 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);
}
}
意识到,如果子流程完成时间太长,则处理 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);
我正在尝试执行 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);
}
}
意识到,如果子流程完成时间太长,则处理 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);