2

我有一个应用程序需要能够在不停止和重新启动的情况下更新自身的一部分(一次一个类)。使用 JavaCompiler API,可以直接生成修改后的类源代码、重新编译、加载和实例化类。我可以在内存中完成这一切(没有从磁盘或网络读取文件)。

应用程序永远不会实例化这样一个类的多个对象。该对象只会有两个或三个引用。当修改后的类被加载并实例化时,所有这些引用都将更改为新对象。我还可以保证在加载修改后的类时,受影响的类中没有任何方法在另一个线程中运行。

我的问题是:我的类加载器在加载与之前加载的类同名的修改类时会遇到问题吗?

如果我没有在类加载器中显式实现加载类的缓存,那会避免问题吗?还是委托给父类加载器仍然会导致问题?

我希望使用我的类加载器的单个实例,但如果有必要,我可以在每次更新类时实例化一个新实例。

注意:我查看了 OSGI,它似乎比我需要的要多得多。

4

2 回答 2

1

在http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html上有一个有用的例子

我们自己做了很多动态类的重新加载(使用 Groovy 进行编译)。请注意,如果您有类依赖项,那么您可能需要在重新加载时重新编译这些依赖项。在开发堆栈中,我们跟踪这些依赖项,然后在依赖项变得陈旧时重新编译。在生产堆栈中,我们选择了非重新加载的 ClassLoader,并在发生任何变化时创建一个新的 ClassLoader。所以你可以做任何一种方式。

顺便说一句 - 您可能会在http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.groovy/groovy-all/1.8.5/groovy/util/GroovyScriptEngine.java#GroovyScriptEngine找到 GroovyScriptEngine如果您想了解他们是如何做到的,这很有趣。

于 2012-03-16T17:02:23.083 回答
0

好的,它应该可以工作:当您加载新类时,它将替换相应表中的类名,并且内存应该是 GC'd。也就是说,我会用一个真正的短程序对其进行艰苦的测试,该程序编译一个非平凡的类并替换它,比如 10,000 次。

于 2012-02-15T17:37:11.717 回答