首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java类加载器独立于jar文件的系统类加载器

Java类加载器独立于jar文件的系统类加载器
EN

Stack Overflow用户
提问于 2014-11-07 09:33:06
回答 3查看 647关注 0票数 1

我试图在程序中加载一个jar文件来调用不同的方法。我有一个类来完成这项工作,但是这个类使用一个依赖于系统类加载器的URLClassLoader加载jar文件,因此,例如,如果加载的jar执行一个System.exit(),它将完成整个应用程序的执行,终止当前正在运行的Java。我的意图是,如果加载的jar最后完成这个操作,它只完成jar,而不是整个应用程序。另外,我希望能够关闭jar,以便在需要时重新启动它。我使用以下代码从jar实例化所需的类,并从我的应用程序中调用这些方法:

代码语言:javascript
复制
// Load a class with classloader = new URLClassLoader(libs);
if(loadclass == null)
    loadclass = Class.forName(classname, true, classloader);
// Execute method
if(met == null)
{
    Constructor constructor;
    if(params != null && params.length > 0)
    {
        constructor = loadclass.getConstructor(new Class[]{Object[].class});
        classinstance = constructor.newInstance(new Object[]{params});
    }
    else
    {
        constructor = loadclass.getConstructor(null);
        classinstance = constructor.newInstance(null);
    }
    return (Object)Boolean.TRUE;
}

// Generic instance
if(classinstance == null)
    classinstance = loadclass.newInstance();

// Method invocation
Method method;
if(params != null)
{
    if(params.length > 1)
        method = loadclass.getMethod(met, new Class[]{Object[].class});
    else
        method = loadclass.getMethod(met, new Class[]{Object.class});
}
else
    method = loadclass.getMethod(met);

method.setAccessible(true);
Object ret;
if(params != null)
{
    if(params.length > 1)
        ret = (Object)method.invoke(classinstance, new Object[]{params});
    else
        ret = (Object)method.invoke(classinstance, params[0]);
}
else
    ret = (Object)method.invoke(classinstance, null);

return ret;

我不知道如何将我的URLClassLoader与系统类加载程序分离。对这一点的任何帮助都是非常感谢的!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-07 09:45:31

System.exit()将退出该进程,而不管类加载器是什么。放弃系统类装入器可以通过不链接类加载器来完成,但是要警告。这意味着所有的系统类都需要重新加载,而且它们不能很好地一起运行。例如,将一个类加载器创建的字符串与另一个包含来自不同类加载器的相同字符的字符串进行比较将失败。

为了防止对System.exit()的调用成功,可以将安全管理器配置为错误。

以下是System.exit()的代码

代码语言:javascript
复制
public void exit(int status) {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkExit(status);
    }
    Shutdown.exit(status);
}

它在安全管理器上调用security.checkExit。这反过来也是这样执行的:

代码语言:javascript
复制
public void checkExit(int status) {
    checkPermission(new RuntimePermission("exitVM."+status));
}

请注意权限exitVM.<number>的使用。有关安全管理器和安装安全管理器的更多详细信息可以阅读这里

票数 0
EN

Stack Overflow用户

发布于 2014-11-07 09:49:36

对System.exit()的调用可以被Java截获。下面的文章讨论使用Java在加载时重写字节代码以插入日志记录语句。同样的方法也可以用来删除对System.exit的调用。

票数 0
EN

Stack Overflow用户

发布于 2014-11-08 11:54:56

要回答System.exit()问题,方法是使用SecurityManager。

在使用URLClassLoader丢弃加载的jar文件的情况下,我发现有一些与之相关的bug:id=6630027

id=6896088

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26798131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档