【问题标题】:Dynamic program updating, runtime compilation, and class loaders动态程序更新、运行时编译和类加载器
【发布时间】:2012-02-15 17:27:06
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 我有一些与此非常相似的东西。您必须指定使用 JDK 才能编译它,否则您将在 JavaCompiler 返回 null 时出错。

标签: java classloader runtime-compilation


【解决方案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 非常有趣。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 2013-11-05
      • 1970-01-01
      • 2019-11-17
      相关资源
      最近更新 更多