【问题标题】:Can Classloading be saved, add to, restored, over and over?类加载可以被保存,添加,恢复,一遍又一遍吗?
【发布时间】:2013-10-08 13:57:30
【问题描述】:

我有一个需要在运行时动态更新类路径的长期程序。

没问题 - 类加载器是一个 URLClassLoader,我调用了“addURL”方法。这一切都适用于一次“更新”迭代。

稍后,当下一个“更新”到来时,我希望能够恢复原始类路径,然后使用更新的条目重复调用“addURL”的过程。然后这个过程在几天/几周后重复。我要克隆原始的类加载器吗?我正在尝试做的事情可能吗?好像任何人都无法分辨,我对类加载器做的不多,而且很茫然。我正在从 java jar 文件运行 groovy,因此直接使用 Java 或 Groovy 解决方案都可以!

编辑

以下每个问题。为了继续正确运行,我需要“刷新”我对类路径所做的原始更改,否则可能会在更新后无意中拾取这些更改。另外,我担心类路径上同时有多个版本的相同 jar。示例:在第一次加载时,我添加了 myJar1、myJar2 和 log4j(

【问题讨论】:

  • 恢复原classpath的原因是什么?

标签: java groovy classpath


【解决方案1】:

如何克隆类加载器?通常你不会。您改为创建一个子加载器。

您不需要将 jars 添加到原始类加载器或尝试更改它,而是需要一个包含要更改的 jars 的子类加载器(并且父级不应拥有它们)。要添加您,请创建一个新的此类 childloader。恢复基本上是由 JVM 的垃圾收集完成的,然后您可以一遍又一遍地进行。但是您应该在这里使用版本化的 jar,因为可能无法覆盖现有的 jar(在 Windows 上,因为 jar 可能保持打开状态)或导致非常奇怪的工件。

如果您的程序本身依赖于您想要更改的 jar 中的类,那么您需要将程序更改为不依赖它 - 或者最好放弃这个想法。

如果由于某种原因你仍然想克隆并且你的加载器真的是一个普通的 URLClassLoader 只从 URL 加载(例如这在 GroovyClassLoader 上不起作用)那么你可以使用反射来访问字段 ucp 和在该对象上的字段 urls,它是一个堆栈,应该包含您正在寻找的信息。但请注意,在 99% 的情况下,这是错误的方法

【讨论】:

  • 对不起,我昨天出去了。我从概念上遵循你所说的,这很有意义。我今天花了一些时间在这上面。基本上,我认为我需要创建自己的扩展 URLClassLoader 的类的实例,让它加载我的类。接下来,只需让它超出范围,然后使用更新的文件集重新创建它。如果这行得通,那正是我想要的!
【解决方案2】:

如果其他人需要这个作为参考,使用@blackdrag 答案,我创建了这个 Java 类:

public class DynamicClassLoader extends URLClassLoader {

    public DynamicClassLoader(ClassLoader parent, URL... urls) {
        super(urls, parent);
    }

    public void addURLs(Iterable<URL> urls) {
        for (URL url : urls) {
            addURL(url);
        }
    }

    public void resetThreadContextLoader() {
        Thread currentThread = Thread.currentThread();
        currentThread.setContextClassLoader(getParent());
    }
}

我的使用模型来自 groovy。因此,为了使用它,我所做的只是:

def myClassLoader = Thread.currentThread().contextClassLoader
dynamicLoader?.resetThreadContextLoader()
dynamicLoader = new DynamicClassLoader(myClassLoader)
dynamicLoader.addURLs(myListOfJarURLs)

完美运行。一切都非常简单——我的 groovy 代码会随着时间的推移重复执行上面的四行代码。如果有以前的动态加载器,则类路径会立即重置并使用更新的 jar 列表进行修改。

【讨论】:

    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2011-12-30
    • 2014-02-11
    • 2014-05-11
    相关资源
    最近更新 更多