Java 您是否可以卸载并重新加载同一个JAR的不同版本,这是第二个JAR的依赖项,而不必重新加载第二个JAR?

Java 您是否可以卸载并重新加载同一个JAR的不同版本,这是第二个JAR的依赖项,而不必重新加载第二个JAR?,java,jar,classloader,dependency-management,Java,Jar,Classloader,Dependency Management,我有一系列包含JAR文件的文件夹,这些JAR充当我的主应用程序的插件。每个单独的JAR文件夹都加载有自己的类加载器,因此可以独立于其他文件夹加载和卸载该JAR文件夹 某些jar依赖于其他jar。在一些情况下,有多个JAR(比如Set A)依赖于同一个单独的JAR(我们称之为BaseJar)。出于这个原因,我为这个BaseJar提供了一个单独的文件夹,这样我就可以只加载一次,而不必在多个地方放置JAR 我需要提供这样的功能,可以禁用这些JAR集合中的任何一个,然后重新加载。因此,对这些插件的任何小

我有一系列包含JAR文件的文件夹,这些JAR充当我的主应用程序的插件。每个单独的JAR文件夹都加载有自己的类加载器,因此可以独立于其他文件夹加载和卸载该JAR文件夹

某些jar依赖于其他jar。在一些情况下,有多个JAR(比如Set A)依赖于同一个单独的JAR(我们称之为BaseJar)。出于这个原因,我为这个BaseJar提供了一个单独的文件夹,这样我就可以只加载一次,而不必在多个地方放置JAR

我需要提供这样的功能,可以禁用这些JAR集合中的任何一个,然后重新加载。因此,对这些插件的任何小更新都可以动态完成,而无需禁用整个应用程序。这就引出了我标题中的问题。如果我要卸载这个BaseJar类,以便对其进行更新,那么有没有办法避免卸载和重新加载SetA jar的所有?我希望他们能够继续正常运作,只要他们的新依赖已经加载了独立类加载器


编辑:为了澄清我的立场,在给出一些答案之后,我已经有了一个正在工作的自定义JarClassLoader。目前,我可以加载我所有的插件并卸载它们。我需要知道是否有可能在不影响其他JAR的情况下批量加载和卸载,这些JAR可能使用另一个JAR中包含的某个类,该类在运行时得到升级


我知道,如果我在升级过程中尝试使用该插件,可能会出现问题,因为它尝试使用的类不再由JVM加载,因此在加载新版本之前不可用。这个新类上传后,会不会导致解决问题?

Jar只包含类文件。这实际上不是依赖性的问题,而是

  • 1加载您想要的JAR(您想要的类)的问题

  • 卸载一个并更换

  • 然后从这些JAR中的类管理对象

1要加载和重新加载JAR,请通过更改类路径:

守则:

 // jarFile is the version of the jar you want to use/overwrite.

  URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();

    Method m = URLClassLoader.class.getDeclaredMethod("addURL", new  Class[]{URL.class});
    m.setAccessible(true);
    m.invoke(urlClassLoader, jarFile.toURI().toURL());
    String cp = System.getProperty("java.class.path");
    if (cp != null) {
        cp += File.pathSeparatorChar + jarFile.getCanonicalPath();
    } else {
        cp = jarFile.toURI().getPath();
    }
    System.setProperty("java.class.path", cp);
注意可能发生的事情:阅读:

并阅读以下警告:

如果在加载所需的类之前执行此操作,则没有问题

如果没有,则更难:

2和3:在进行更改时,不应该有“旧”类的对象,否则结果应该是不可预测的。你的程序有责任摆脱它,还有类加载器

请参阅下面的内容,其中建议为每个Jar创建自己的类加载器


就实际加载和卸载jar而言,我认为Stackoverflow上的资源已经非常清楚了,我已经有了一个工作的JarClassLoader。你说我的问题不是依赖,但确实是。我已经加载和卸载了我的JAR,现在我需要知道JAR是否可以解决对其他JAR中的类文件的依赖关系,这些JAR被卸载后又重新加载到新版本。@Seb我说这不是依赖性的问题。如果您确切地知道哪些JAR和其中的类需要哪些其他JAR/类,那么您应该在每个JAR/类中实现您的依赖性逻辑,方法是加载好的JAR/类。我的问题是,在我卸载并加载另一个JAR使用的这个类的新修改版本之后,这个JAR是否能够解析对这个更新类的访问?是否需要重新加载它自己才能看到这个更新的类,或者在JVM中必要时会发生这种解析?请参见:-它基于类(和包),而不是基于JAR。这些加载通常是独立的。嗯,我不关心同时运行两个版本的sameclass,但我想我能理解你想表达的意思。我的问题本质上可以归结为“如果一个类可以访问JVM中的另一个类,那么它何时以及如何解决?”。但我也找不到这个问题的最终答案。所以你想重新发明OSGi?