动态重新加载jar文件内容

时间:2013-01-31 09:25:00

标签: java dynamic bytecode dynamic-class-loaders

我的应用程序的类路径中有一个jar文件。在运行时,我向jar文件添加新类,有时还修改现有类的字段/方法。目前我正在使用URLClassLoader动态加载类。动态添加的新类正确加载,我可以在运行时使用它们。但它无法重新加载在运行时修改的现有类。我阅读了许多文章,声明我们需要显式处理重新加载,因为在类的所有引用都被销毁之前,不会重新加载一次加载的类。我也尝试了我找到的示例代码,但没有一个能够工作。

有人能建议我适当的重装方法吗?任何示例代码都将受到高度赞赏。

2 个答案:

答案 0 :(得分:4)

通常要重新加载一个类,你需要卸载整个类加载器。即删除对该类加载器加载的所有类的所有引用。

另一种选择是使用检测来更改现有类的字节代码。这通常带有限制,不断变化的领域是你无法做到的。即,那种类型的物体必须以某种方式翻译。

我通常所做的是提供快速启动/重启的服务。这样,您可以通过在我的IDE中按Run轻松地重新启动需要更新代码的过程。这也最大限度地缩短了部署时间。

答案 1 :(得分:1)

  1. 原则上,不能使用相同的类加载器重新加载已经加载的类。
  2. 对于新的加载,有必要创建一个新的类加载器,从而加载该类。
  3. 使用URLClassLoader有一个问题,那就是jar文件保持打开状态。
  4. 如果您有一个由URLClassLoader的不同实例从一个jar文件加载的多个类,并且在运行时更改了jar文件,通常会收到以下错误:java.util.zip.ZipException: ZipFile invalid LOC header (bad signature)。错误可能有所不同。
  5. 为了避免发生上述错误,必须使用给定的jar文件在所有close上使用URLClassLoader方法。但这实际上是导致整个应用程序重新启动的解决方案。

更好的解决方案是修改URLClassLoader,以便将jar文件的内容加载到RAM缓存中。这不再影响其他从同一jar文件读取数据的URLClassloader。然后可以在应用程序运行时自由更改jar文件。例如,您可以为此目的对URLClassLoader进行以下修改:in-memory URLClassLoader