2

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

任何人都可以建议我重新加载的正确方法吗?任何相同的示例代码都将受到高度赞赏。

4

2 回答 2

4

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

另一种选择是使用检测来更改现有类的字节码。这通常带有限制,并且更改字段是您无法做到的。即,必须以某种方式翻译该类型的对象。

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

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

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

于 2020-07-09T08:15:15.660 回答