Java Groovy GroovyClassLoader JVM缓存和更新加载的类

Java Groovy GroovyClassLoader JVM缓存和更新加载的类,java,groovy,jvm,classloader,Java,Groovy,Jvm,Classloader,我正在用GroovyClassLoader测试jar的动态加载。我们将经常更新JAR,因此在不重新启动JVM的情况下进行更改时,我们需要重新加载JAR(更具体地说,是类)。这可能吗 我做了一次classLoader.addUrl(path),JAR被加载到内存中。然后,我可以在后续脚本中生成实例,而无需再次加载该类(这看起来像是缓存,很好) 问题是我尝试了classLoader.clearCache(),但似乎没有任何效果.classCache和.sourceCache为空。但是,我仍然可以生成

我正在用
GroovyClassLoader
测试jar的动态加载。我们将经常更新JAR,因此在不重新启动JVM的情况下进行更改时,我们需要重新加载JAR(更具体地说,是类)。这可能吗

我做了一次
classLoader.addUrl(path)
,JAR被加载到内存中。然后,我可以在后续脚本中生成实例,而无需再次加载该类(这看起来像是缓存,很好)

问题是我尝试了
classLoader.clearCache()
,但似乎没有任何效果
.classCache
.sourceCache
为空。但是,我仍然可以生成实例。我尝试获取父类加载器,但它没有显示加载的包/类的任何痕迹。我不知道它住在哪里

我也读过这篇文章,不,我没有在JVM中编译这个类

我不认为我的代码是相关的,但无论如何,它在这里

GroovyClassLoader classLoader = new GroovyClassLoader()
def jarFile = new File("C:/sandbox-test-0.1.0-SNAPSHOT.jar")
classLoader.addURL(jarFile.toURI().toURL())
def mySand = Class.forName("com.test.Sandbox").newInstance()
println mySand.dump()

Sascha向我展示了一个非常简单的解决方法

要“更新”类加载器,只需将现有类加载器置空并重新生成:

classloader = null
classloader = new GroovyClassLoader()
classLoader.addURL(jarFile.toURI().toURL())
只有在请求类时才需要类加载器


在我的用例中,这很简单。也许其他人会有更复杂的情况,可能会使这不起作用

如果我错了,请纠正我,我的理解是您正在尝试用类路径中的jar的更新版本替换现有的jar。如果是这样的话,用新的jar路径调用classLoader.addUrl(path)不就是简单地将jar的新版本添加到类路径的末尾吗?我相信这样做的结果是,您现在在类路径中有两个jar版本,更重要的是,Java将在类路径中找到第一个列出的旧版本,并且永远不会从新jar加载类,除非它们是原始jar中不存在的新类。这的确是事实,也是问题所在。在一位了不起的Groovy大师的帮助下,我现在正致力于以下解决方案:1。编写一个新类,用于在开始时创建和操作一个新的UrlClassLoader(),然后加载我的所有JAR URL。该类加载器将作为静态变量存储在JVM中,允许我的所有自定义代码找到该类加载器。最重要的是,我的“Updater”进程将每10分钟运行一次,如果它检测到任何JAR的更改,它会将该变量设置为null,然后重新创建,在进程中提取JAR的新副本。