繁体   English   中英

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

[英]Java class loader independent from the system class loader for jar files

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

// 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与系统类加载器分离。 到此为止的任何帮助,不胜感激!

无论Class Loader是什么, System.exit()都将退出进程。 可以通过不链接类加载器来放弃系统类加载器,但是要注意。 这意味着所有系统类都需要重新加载,并且不能很好地配合使用。 例如,将一个类加载器创建的字符串与另一个来自不同类加载器的包含相同字符的字符串进行比较将失败。

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

这是System.exit()的代码

public void exit(int status) {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkExit(status);
    }
    Shutdown.exit(status);
}

它在安全管理器上调用security.checkExit 依次实现如下:

public void checkExit(int status) {
    checkPermission(new RuntimePermission("exitVM."+status));
}

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

Java代理可以拦截对System.exit()的调用。 本文讨论使用Java代理在加载时重写字节码以插入日志记录语句。 可以使用相同的方法来删除对System.exit的调用。

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

在使用URLClassLoader丢弃加载的jar文件的情况下,我发现存在一些相关的错误: http : //bugs.java.com/bugdatabase/view_bug.do?bug_id=6630027

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6896088

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM