当前位置: 首页 > 知识库问答 >
问题:

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

郎健柏
2023-03-14

我试图在程序中加载一个jar文件来调用不同的方法。我有一个类来完成这项工作,但是该类使用URLClassLoader加载jar文件,它依赖于系统类加载程序,因此,例如,如果加载的jar执行系统。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。任何帮助,这一点是赞赏!

共有3个答案

洪高阳
2023-03-14

回答系统。exit()issue,方法是使用SecurityManager。

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

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

西门奇希
2023-03-14

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

上官扬
2023-03-14

系统。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的权限

 类似资料:
  • 问题内容: 我们知道我们可以使用以下方法覆盖System 类加载器: 那么,既然它本身是一个类,它是由谁加载的? 我们如何获得该“元”类加载器的类文件? 问题答案: 从Javadoc中获取: 如果在首次调用此方法时定义了系统属性“ java.system.class.loader”,则该属性的值将作为要作为系统类加载器返回的类的名称。 该类使用默认的系统类加载器加载, 并且必须定义一个公共构造函数

  • 我将Jetty(8和9)与LZ4压缩一起使用,我想使用LZ4的本机实现,它是C库的本机绑定。为了实现这一点,LZ4类应该用系统类加载器加载。 所以我的问题是,如何用Jetty中的系统类加载器加载一个外部jar。 将lib放入$jetty。home/lib/ext没有帮助,因为它是用扩展类加载器而不是系统加载器加载的。

  • 我需要加载不同服务器上存在的类文件,并在类文件中执行方法。我不想使用超文本传输协议或RMI,但想应用这种方法。我正在看URLClassLoader,但没有得到任何地方。有人能给我一个从不同服务器加载类的例子吗?

  • 问题内容: 我有一个简单的程序,需要显示图像。我知道如何从Eclipse运行代码,也知道如何从JAR文件运行,但是我想要一个在两种情况下都可以使用的解决方案。 Eclipse项目就是这样的: 可在Eclipse中运行的代码段: 适用于JAR的文件(全部在一个JAR文件中): 为了使单个代码在两种情况下都能正常工作,我需要更改什么? 问题答案: 将文件夹放在文件夹中,Eclipse会将图像复制到目标

  • 本文向大家介绍classloader类加载器_基于java类的加载方式详解,包括了classloader类加载器_基于java类的加载方式详解的使用技巧和注意事项,需要的朋友参考一下 基础概念 Classloader 类加载器,用来加载 Java 类到 Java 虚拟机中。与普通程序不同的是。Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机

  • 主要内容:JVM架构图,1.类加载子系统作用,2.类加载器分类,3.双亲委派机制,4. 沙箱安全机制,5.其他JVM架构图 1.类加载子系统作用 类加载子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识; ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定 加载的类信息存放于一块成为方法区的内存空间。除了类信息之外,方法区还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是