如何允许子类加载器退出VM?

时间:2011-05-18 16:51:57

标签: java security classloader

考虑一个Web Start应用程序,它将一些jar放在一个目录中,然后执行其中一个。想想一个启动器/包装器。

为实现这一目标,我创建了一个指向jar的子URL类加载器,加载一个类并告诉它运行它的main()。在其中创建JFrame EXIT_ON_CLOSE默认关闭操作。

类加载器的执行方式如下:

URLClassLoader cl = new URLClassLoader(
    new URL[] { new File(tgtPath + "/inner.jar").toURI().toURL() },
    Launcher.class.getClassLoader());
Class main = cl.loadClass("inner.Main");
main.getMethod("main", String[].class).invoke(
    null, 
    new Object[] { new String[] { "My arg" } });

不幸的是,它会产生以下异常:

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at outer.Launcher.main(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.javaws.Launcher.executeApplication(Launcher.java:1804)
at com.sun.javaws.Launcher.executeMainClass(Launcher.java:1750)
at com.sun.javaws.Launcher.doLaunchApp(Launcher.java:1512)
at com.sun.javaws.Launcher.run(Launcher.java:130)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.lang.SecurityManager.checkExit(SecurityManager.java:744)
at javax.swing.JFrame.setDefaultCloseOperation(JFrame.java:372)
at inner.Main.main(Unknown Source)
... 14 more

我认为原因是不允许子类加载器退出VM。如何禁用或绕过此限制?

编辑 - 回复评论:我真的希望内部流程能够调用System.exit,而不是将应用和启动器连接在一起。

JNLP的安全设置:

<security>
  <all-permissions/>
</security>

0 个答案:

没有答案