Java,运行时类重载

发布于 2024-10-02 13:03:27 字数 303 浏览 5 评论 0原文

我正在寻找一种在运行时将类重新加载到 Java 中的方法。动机是为了提高调试效率。该应用程序是典型的客户端/服务器设计,同步处理请求。为每个请求实例化一个“处理程序”对象。这是我打算动态替换的唯一类。由于每个请求都处理一个新实例,因此重新加载此类不会产生任何副作用。简而言之,我不想每次对该模块进行更改时都重新启动整个应用程序。

在我的设计中,Java 进程意识到 .class 文件已在请求之间的类路径中更新。发生这种情况时,“处理程序”类将被卸载并加载一个新类。

我知道我可以使用 classLoader 接口来加载新类。我似乎很难找到正确的“卸载”方法。

I am looking for a way to reload a class into Java at runtime. The motivation is to make debugging more efficient. The application is a typical client/server design that synchronously processes requests. A "handler" object is instantiated for each request. This is the only class I intend to dynamically replace. Since each request deals with a fresh instance, reloading this class won't have any side-effects. In short, I do not want to restart the entire application every time there is a change to this module.

In my design, the Java process becomes aware that a .class file has been updated in the classpath in between requests. When this happens, the "handler" class is unloaded and a new one is loaded.

I know I can use the classLoader interface to load in a new class. I seem to be having trouble finding the proper way of "unloading".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

睡美人的小仙女 2024-10-09 13:03:27

如果没有对类的剩余引用,类将像任何其他对象一样被卸载和垃圾收集。这意味着该类必须没有可访问的实例(由该特定类加载器实例加载),并且类加载器实例本身也必须符合垃圾回收的条件。

所以基本上,您所要做的就是创建一个新的类加载器实例来加载该类的新版本,并确保不保留对旧版本实例的引用。

Classes will be unloaded and garbage collected like any other object, if there is no remaining reference to them. That means there must be no reachable instance of the class (as loaded by that particular classloader instance) and the classloader instance itself must be eligible for garbage collection as well.

So basically, all you have to do is to create a new classloader instance to load the new version of the class, and make sure that no references to instances of the old version remain.

无敌元气妹 2024-10-09 13:03:27

我相信你实际上需要有一个类加载器的层次结构,并且为了重新加载,你实际上摆脱了低级类加载器(通过正常的 GC 手段),从而摆脱了它加载的所有类。据我所知,Java EE 应用服务器使用这种技术来重新加载应用程序,并且当一个类加载器中加载的框架代码想要使用其他地方加载的类时,会产生各种有趣的结果。

I believe that you actually need to have a hierarchy of classloaders, and in order to reload you actually get rid of the low level classloader (by normall GC means), and hence all the classes it loaded. So far as I know this technique is used by Java EE app servers for reloading applications, and there's all manner of fun results when framework code loaded in one classloader wants to use classes loaded somewhere else.

执着的年纪 2024-10-09 13:03:27

截至 2015 年,java 的类重新加载功能也缺失了。

  • 使用OSGi创建类重新加载应用程序。
  • 使用jrebel进行测试。还有其他一些也做同样的事情。
  • 使用应用程序服务器并将您想要重新加载到单独的 Web 应用程序中的部分外部化。然后继续部署/取消部署。由于旧的 ClassLoader 实例悬空,您最终会遇到一些永久代空间溢出类型的错误。
  • 使用脚本运行程序来执行部分可更改的代码。 JSR-223 Java 脚本 API 支持脚本语言“Java”。

我写了一系列关于类重新加载的文章。但所有这些方法都不利于生产。

恕我直言,这个类重新加载在 java 中很混乱,而且不值得尝试一下。但我非常希望这是 java 中的一个规范。

As of 2015 also java's class reloading is a missing feature.

  • Use OSGi to create a class reloading application.
  • Use jrebel for testing. There are a few others which does the same thing.
  • Use application server and externalize the parts which you want to reload into a separate web application. Then keep deploying/undeploying. You will eventually get some perm gen space overflow kind of errors due to dangling old ClassLoader instances.
  • Use a script runner to execute parts of changeable code. JSR-223 Java Scripting API support for the scripting language "Java".

I had written a series about class reloading. But all of those methods are not good for production.

IMHO this class reloading is messy in java and its not worth trying it. But I would very much like this to be a specification in java.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文