禁止调用System.exit的方法

11

我想阻止某些JAR文件调用System.exit(int);

这些JAR文件将由外部团队开发,并由我们的“容器”应用程序加载。

我的第一个反应是使用Java安全管理器:

-Djava.security.manager-Djava.security.debug=all

使用最简单的 ${user.home}/.java.policy 文件:

grant {};

虽然我无法再调用类似 System.getProperties() 这样的方法(因为我没有 java.util.PropertyPermission),但我可以执行 System.exit(0)!!

选项 java.security.debug=all 会在控制台输出以下内容:

scl: getPerms ProtectionDomain (file: my-bin-path <no sign certificates>)
sun.misc.Launcher $ AppClassLoader @ 10385c1
<no principals>
java.security.Permissions @ 15b7986 (
(java.lang.RuntimePermission exitVM)
(java.io.FilePermission \my-bin-path\- read)
)

为什么我的bin路径中的所有类都被授予java.lang.RuntimePermission exitVM权限?

谢谢。


显然,默认情况下授予java.lang.RuntimePermission exitVM权限,也许您需要明确拒绝它。 - Romain
我希望默认情况下启用exitVM权限。如果一段Java代码执行到结尾,则可能需要隐式调用System.exit(0)来告诉虚拟机它已完成。 - CLo
我假设你想知道如何关闭它,建议编辑问题以明确询问。 - CLo
系统范围的策略文件是什么样的?${java.home}/lib/security/java.security - ptomli
据我所知,java.policy文件只授予权限。因此,我认为“不启用它<=>让它关闭”是因为jre/lib/security/java.policy未授予java.lang.RuntimePermission exitVM的权限。 - kiki
在 java.lang.RuntimePermission 的 javadoc 中找到: 权限目标名称为 "exitVM.{退出状态}": 注意:"exitVM.*" 权限会自动授予从应用程序类路径加载的所有代码,因此使应用程序能够终止自身。 - kiki
3个回答

3
根据错误报告http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4286238,策略文件没有禁止System.exit()调用。我正在使用Java 1.6运行一个应用程序,尽管它被“解决”,但仍然出现这个错误。与OP类似,我有一个系统范围的策略文件,其中不包括exitVM的权限,但我能够退出应用程序而不会抛出任何异常。
我的理解是,包括自定义策略文件意味着除了策略文件中包含的权限之外,所有权限都被列入黑名单。因为没有包括exitVM,所以应该被禁止(覆盖MicSim提到的默认权限)。但事实并非如此。

2
RuntimePermission的Javadoc中可以看到:

注意:所有从应用程序类路径加载的代码都会自动获得“exitVM.*”权限,从而使应用程序能够终止自身。

阅读此内容,似乎您必须编写自己的SecurityManager来明确拒绝此权限。(有关示例,请参见此答案:Prevent System.exit to actually exit the JVM

1

或者你可以使用AOP来拦截System.exit。自己做的话,需要创建自己的类加载器并使用BPEL跟踪System.exit,并修补那些调用。真的没有太大的工作量。


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