Java,运行时类重载
我正在寻找一种在运行时将类重新加载到 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果没有对类的剩余引用,类将像任何其他对象一样被卸载和垃圾收集。这意味着该类必须没有可访问的实例(由该特定类加载器实例加载),并且类加载器实例本身也必须符合垃圾回收的条件。
所以基本上,您所要做的就是创建一个新的类加载器实例来加载该类的新版本,并确保不保留对旧版本实例的引用。
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.
我相信你实际上需要有一个类加载器的层次结构,并且为了重新加载,你实际上摆脱了低级类加载器(通过正常的 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.
截至 2015 年,java 的类重新加载功能也缺失了。
我写了一系列关于类重新加载的文章。但所有这些方法都不利于生产。
恕我直言,这个类重新加载在 java 中很混乱,而且不值得尝试一下。但我非常希望这是 java 中的一个规范。
As of 2015 also java's class reloading is a missing feature.
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.