Java中的ProcessBuilder没有抛出子进程异常。

3
我将尝试使用ProcessBuilder在Java中执行一个jar文件。当由ProcessBuilder调用的子进程抛出任何异常时,ProcessBuilder不会捕获异常,执行将持续进行。
以下是我的代码:
try {
ProcessBuilder pb = new ProcessBuilder("java", "-jar", CommonConstants.jarFileLocation,
                fileEntry.getAbsolutePath(), CommonConstants.commonFileLocation);       
        Process p = pb.start();         
    } 
catch (Exception e) {           
        e.printStackTrace();    
    }

catch块应该在子进程抛出任何异常时打印它。然而,它从来没有这样做。 我错过了什么吗?

2个回答

2

已完成在控制台上打印的操作...

我使用了ProcessBuilder inheritIO方法,它将子进程标准I/O的源和目的地设置为与当前Java进程相同。

因此,修改后的代码如下...

try {
ProcessBuilder pb = new ProcessBuilder("java", "-jar", CommonConstants.jarFileLocation,
                fileEntry.getAbsolutePath(), CommonConstants.commonFileLocation).redirectError(Redirect.INHERIT);       
        Process p = pb.start();         
    } 
catch (Exception e) {           
        e.printStackTrace();    
    }

然而,需要它被catch块捕获。需要帮助!


0

它不会在 catch 块中被捕获,因为子进程在启动时除了 IOException 和等待完成时的 InterruptedException 外不会抛出任何异常。你需要解析从 stderr 流中获取的内容并自行抛出适当的异常。 这意味着你必须准确知道错误的样式并相应地处理。 以下是一个使用 Java 8 的示例,使用 CompletableFuture。你也可以使用 Thread 从输入流中读取并解析错误消息。

try {
    ProcessBuilder pb = new ProcessBuilder("java", "-jar", 
                                CommonConstants.jarFileLocation,
                                fileEntry.getAbsolutePath(), 
                                CommonConstants.commonFileLocation);

    Process p = pb.start();
    InputStream errorStream = process.getErrorStream();
    
    CompletableFuture<List<String>> errorMessages = CompletableFuture.supplyAsync(() -> {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(errorStream))) {
            return br
                    .lines()
                    .collect(Collectors.toList());
        } catch (IOException e) {
            return new ArrayList<>();
        }
    });

   int exitCode = process.waitFor();
   
   for (String errorMessage: errorMessages.get()) {
        if (errorMessage.contains("reason X")) {
             throw new ReasonXException(); // assuming we defined this custom exception somewhere
        }
        if (errorMessage.contains("reason Y")) {
             throw new ReasonYException(); // assuming we defined this custom exception somewhere
        }
        throw new Exception(errorMessage);
   }

   if (exitCode != 0) {
       throw new Exception("Program exited with a non-zero status code");
   }
}
catch (Exception e) {           
    e.printStackTrace();   // catching generic Exception here for brevity, you should catch more specific exceptions in your own code.
}

请注意,这并不是一个通用的解决方案,可能需要根据您的用例进行修改。这个示例只在每行只有一个错误信息时有效。所以如果对您而言不是这种情况,那么您需要相应地调整错误信息处理逻辑,可能需要更复杂的机制将它们映射到“最终”错误消息列表。
另外,如果您想使用这种方法,请不要在“Process”上调用“inheritIO()”,因为“getErrorStream()”将返回一个空流,您将无法获取任何错误消息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接