Java 捕获运行时异常';“跨境”;在命令行中——从一个jar开始,然后抛出到另一个jar中
我在开发的系统中显式地调用JVM,比如说Java 捕获运行时异常';“跨境”;在命令行中——从一个jar开始,然后抛出到另一个jar中,java,jvm,classpath,runtime.exec,Java,Jvm,Classpath,Runtime.exec,我在开发的系统中显式地调用JVM,比如说systemA。这是根据规范——我必须在另一个jre实例中处理该命令 执行此操作的命令是 java -cp thisJar.jar;thatJar.jar -Djava.security.manager=mySM -Djava.security.policy=my.policy TheClass ,我使用Process和ProcessBuilder运行此命令: StringBuilder sbResult = new StringBuilder(
systemA
。这是根据规范——我必须在另一个jre实例中处理该命令
执行此操作的命令是
java -cp thisJar.jar;thatJar.jar -Djava.security.manager=mySM -Djava.security.policy=my.policy TheClass
,我使用Process
和ProcessBuilder
运行此命令:
StringBuilder sbResult = new StringBuilder();
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process p=null;
try {
p = builder.start();
p.waitFor();
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String line = "";
while ((line = br.readLine()) != null)
sbResult.append(line+System.getProperty("line.separator"));
} catch (Throwable t) { commandResult.error.add(t); }
commandResult.text = sbResult.toString();
} catch (Throwable e1) { commandResult.error.add(e1); }
类型CommandResult
非常简单:
public static class CommandResult {
public String text="";
public List<Throwable> error = new LinkedList<>();
public int statusCode;
}
及
仍然没有看到这个例外。与以前没有变化 Java应用程序之间没有“跨边界”抛出异常的概念。分叉进程和子进程是在不同JVM中运行的完全独立的进程。通常会在子流程的错误流上打印异常。为了检测这样的异常或错误流上打印的任何错误,您需要以与您对输出流所做的类似的方式读取该流 但是,在这种情况下,您应该删除语句
builder.redirectErrorStream(true)因为此语句将错误流重定向到输出流,因此很难区分这两种类型的输出。为了捕获错误输出,只需阅读进程#getErrorStream
:
sbResult = new StringBuilder();
// this read the error stream of the subprocess
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()))) {
String line = "";
while ((line = br.readLine()) != null) {
sbResult.append(line+System.getProperty("line.separator"));
}
// errorString would contain the error generated by the subprocess, including thrown exceptions
commandResult.errorString = sbResult.toString();
}
Java应用程序之间没有“跨边界”抛出异常的概念。分叉进程和子进程是在不同JVM中运行的完全独立的进程。通常会在子流程的错误流上打印异常。为了检测这样的异常或错误流上打印的任何错误,您需要以与您对输出流所做的类似的方式读取该流
但是,在这种情况下,您应该删除语句builder.redirectErrorStream(true)因为此语句将错误流重定向到输出流,因此很难区分这两种类型的输出。为了捕获错误输出,只需阅读进程#getErrorStream
:
sbResult = new StringBuilder();
// this read the error stream of the subprocess
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()))) {
String line = "";
while ((line = br.readLine()) != null) {
sbResult.append(line+System.getProperty("line.separator"));
}
// errorString would contain the error generated by the subprocess, including thrown exceptions
commandResult.errorString = sbResult.toString();
}
你能发布更新的代码吗?您是否删除了builder.redirectErrorStream(true)
?如果你能让你的问题更具可复制性,那会对你有更大的帮助。让我再看看。在这个prj中有很多中间人——很难复制。请看更新。这是因为“跨国界”的事情。但可能是因为两个JVM——而不是两个JAR。以前在其他地方给了我一些其他的不幸,我解决了。你能发布更新的代码吗?你是否删除了builder.redirectErrorStream(true)
?如果你能让你的问题更具可复制性,那会对你有更大的帮助。让我再看一些。在这个prj中有很多中间人——很难复制。这是因为“跨境”的事情。但可能是由于两个JVM,而不是两个JAR。以前在其他地方给了我一些其他问题,我解决了它们。通过更新,异常堆栈跟踪应该存储在commandResult.text
string字段中。commandResult.error
不会捕获子流程中的任何异常。这不是它在两个独立Java进程中的工作方式。我正在查找它们--.text和.error。原则上,您可以使用调试接口设置异常断点,但这不是您希望在生产环境中执行的操作。相反,您应该在应用程序之间实现某种形式的显式通信通道。随着更新,异常堆栈跟踪应该存储在commandResult.text
string字段中。commandResult.error
不会捕获子流程中的任何异常。这不是它在两个独立Java进程中的工作方式。我正在查找它们--.text和.error。原则上,您可以使用调试接口设置异常断点,但这不是您希望在生产环境中执行的操作。相反,您应该在应用程序之间实现某种形式的显式通信通道
sbResult = new StringBuilder();
// this read the error stream of the subprocess
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()))) {
String line = "";
while ((line = br.readLine()) != null) {
sbResult.append(line+System.getProperty("line.separator"));
}
// errorString would contain the error generated by the subprocess, including thrown exceptions
commandResult.errorString = sbResult.toString();
}