如何在Java shutdown hook中获取返回代码

7

我需要根据我的应用程序结果修改JVM的返回代码。

但是明确调用System.exit(code)存在风险,因为该应用程序很复杂,难以确定运行线程的结束时间。

因此,我想到使用关闭挂钩来在JVM退出之前修改返回代码。

但是有一个问题,我如何获取JVM的原始返回代码,因为它可能是一个错误代码而不是0。


但是如何在主线程中知道原始的退出代码呢?如果它应该是-1,但我在关闭挂钩中将其设置为1,那该怎么办? - Leslie Wu
你想要如何处理原始的退出代码,因为你希望根据你的应用程序结果来设置代码。 - ravthiru
我担心原始代码是错误代码,我不应该修改错误代码。 - Leslie Wu
我删除了我的评论,因为它显然是错误的,但如果这是你的应用程序,知道何时退出不应该很难。为什么不创建一个特殊的Throwable(以绕过catch(Exception ...)),在主方法中捕获它?然后相应地更改/关闭而无需使用钩子? - efekctive
2个回答

5
不应在关闭钩子中调用退出方法,System.exit(status) 内部调用 Runtime.getRuntime().exit(status); 这将导致应用程序无限期地阻塞。根据JavaDoc文档描述,如果在虚拟机开始关闭序列后调用此方法,则如果正在运行关闭钩子,此方法将无限期地阻塞。您无法访问status,因为即使在所有关闭钩子被调用后,状态也可能发生变化。

0

由于关闭挂钩和退出状态不兼容,您可以创建一个 Throwable,其唯一功能是在主方法中被捕获。然后 catch 块就成为了您的关闭块。在那里,您可以调用 System.exit(),甚至保留您的关闭代码(如果需要的话)。

class Emergency extends Throwable{
    int exit = 0;
}

public final class Entry {

    public static void main(String[] args){
            try {
                throw new Emergency();
            } catch (Emergency e) {
                // Shut down the app

            }
    }

}

如果中间存在捕获和记录异常的机制,则可能会失败。 - Brian McCutchon
我猜如果你直接扩展Throwable而不是Exception,它可能会起作用。 - Brian McCutchon
它必须扩展Throwable,因为这些异常很少被捕获。我马上会发布一个小片段。 - efekctive

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