Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 类加载可以被保存、添加、恢复、反复吗?_Java_Groovy_Classpath - Fatal编程技术网

Java 类加载可以被保存、添加、恢复、反复吗?

Java 类加载可以被保存、添加、恢复、反复吗?,java,groovy,classpath,Java,Groovy,Classpath,我有一个长寿命的程序,需要在运行时动态更新类路径 没问题-类加载器是URLClassLoader,我调用'addURL'方法。这一切对于一次“更新”迭代都非常有效 稍后,当下一个“更新”到达时,我希望能够恢复原始类路径,然后用更新的条目重复调用“addURL”的过程。然后,此过程在几天/几周后重复。我是否克隆原始类加载器?我想做的事可能吗?好像有人还不知道,我对类加载器做得不多,所以我很茫然。我从一个JavaJAR文件运行groovy,所以直接使用java或groovy解决方案都可以 编辑 根据

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

没问题-类加载器是URLClassLoader,我调用'addURL'方法。这一切对于一次“更新”迭代都非常有效

稍后,当下一个“更新”到达时,我希望能够恢复原始类路径,然后用更新的条目重复调用“addURL”的过程。然后,此过程在几天/几周后重复。我是否克隆原始类加载器?我想做的事可能吗?好像有人还不知道,我对类加载器做得不多,所以我很茫然。我从一个JavaJAR文件运行groovy,所以直接使用java或groovy解决方案都可以

编辑


根据下面的问题。为了继续正确运行,我需要“刷新”我对类路径所做的原始更改,否则这些更改可能在更新后被无意中拾取。另外,我关心的是在类路径上同时有相同JAR的多个版本。示例:在第一次加载时,我添加了myJar1、myJar2和log4j(如何克隆类装入器?通常不会。而是创建一个子装入器

您需要一个子类加载器,其中包含您想要更改的jar(父类不应该拥有它们),而不是将jar添加到原始类加载器或试图更改它。若要添加,请创建一个新的此类子加载程序。还原基本上是通过JVM的垃圾收集完成的,然后您可以反复执行。但您应该在此处使用版本化的jar,因为覆盖现有jar可能是不可能的(在windows上,因为jar可能保持打开状态)或导致非常奇怪的工件

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


如果出于某种原因,您仍然希望采用克隆的方式,并且如果您的加载程序确实是一个普通的URLClassLoader,则仅从URL加载(对于exmaple来说,这在GroovyClassLoader上不起作用)然后,您可以使用反射来访问字段ucp和该对象上的字段URL,这是一个堆栈,应该包含您正在查找的信息。但请注意,在99%的情况下,这是一种错误的方式

如果其他人需要,请使用@blackdrag-answer,我创建了以下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代码将随着时间的推移重复执行上面的四行。如果以前有dynamicLoader,则会立即重置类路径并使用更新的JAR列表进行修改。

恢复原始类路径的原因是什么?对不起,我昨天出去了。我按照你说的c执行从概念上讲,这是非常有意义的。我今天花了一些时间在这方面。基本上,我认为我需要创建我自己的扩展URLClassLoader的类实例,让它加载我的类。接下来,简单地让它超出范围,然后用更新的文件集重新创建它。如果这样做有效,这正是我想要的!
def myClassLoader = Thread.currentThread().contextClassLoader
dynamicLoader?.resetThreadContextLoader()
dynamicLoader = new DynamicClassLoader(myClassLoader)
dynamicLoader.addURLs(myListOfJarURLs)