在运行时更新 Java 代码
大约一年前,我偶然发现了 Java 中的一个很好的功能,但我一生都无法再找到它。
通过一些神奇的接口,显然可以声明一些类或函数在运行时可替换。
我找到了一个很好的示例指南,其中有人运行了一个简单的小程序,打印了一条特定的消息,然后他使用一种我不再记得的方法更新了该程序,突然间该程序用新的打印功能替换了旧的打印功能。
我尝试过通过 Java API 来激发我的记忆,也尝试过谷歌搜索,但没有成功。这里有人可以帮忙吗?
about a year ago I stumbled across a nice feature in Java that I cannot for the life of me find again.
Through some magic interface it was apparently possible to declare some classes or functions replaceable during runtime.
I found a nice example guide of someone who ran a simple little program that printed a certain message, he then updated the program using a method I cannot remember anymore and all of a sudden the program had replaced that old print function with a new one.
I've tried looking through the Java API to spark my memory as well as googling but without success. Can anyone here help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
各种应用程序容器都可以做到这一点。
基本上,您需要在新的 ClassLoader 中重新加载类(除非您正在谈论在调试器下执行此操作,在这种情况下,可以使用完全不同的 API)。
在我看来,这种事情很少值得麻烦:设计所有东西以便可以重新加载比设计它可以在新进程中完全重新启动要困难得多。如果进程中只加载了一个版本,那么也更容易确定到底正在运行什么代码。
能够进行演示是一件很棒的事情,但对于大多数应用程序来说这是不值得的。当然,这都是我的观点:)
请注意,一个值得注意的例外是无需重新启动容器即可重新加载 Web UI 层的能力:这可以让生活变得更加轻松。
Various app containers can do this.
Basically you'd need to reload the class in a new
ClassLoader
(unless you're talking about doing this under the debugger, in which case there are completely different APIs available).In my opinion, this kind of thing is rarely worth the hassle: designing everything so that it can be reloaded is considerably harder than designing it so it can be completely restarted in a new process. It's also easier to be sure exactly what code is running if there's only ever one version loaded in the process.
It's a neat thing to be able to demo, but for most applications it's not worth it. All in my opinion, of course :)
Note that one notable exception is the ability to reload web UI layers without restarting the container: that can make life much easier.
Java 1.4 中添加了HotSwap技术,并支持在运行时替换类文件。该功能是通过 instrumentation 包。我认为您也可以通过 JPDA 界面。
这里还引用了我认为首先描述 HotSwap 机制的研究论文:
否则,您可以使用类加载器,正如其他提到的,但它只能提供动态类加载,而不是替换。同一个类加载两次将被视为两种不同的类型。然而,与接口和/或一些反射相结合,它可以提供在运行时更新应用程序的方法。
这里引用了一篇关于类加载器的精彩论文及其用法:
我不会详细讨论这是好是坏,因为这不是你的问题,但我认为支持运行时软件进化是很棒的 - 太糟糕了 JSR-117 从未成功!
The HotSwap technology was added to Java 1.4 and enable class file replacement at run-time. The feature is provide through the
redefineClasses
method of the instrumentation package. I think you can also do that through the JPDA interface.Here is also a reference to what I believe is the research paper that describe the HotSwap mechanism first:
Otherwise you can use Classloader, as the other mentionned, but it only provides dynamic class loading, not replacement. The same class loaded twice will be considered as two different types. Combined with interface and/or a bit of reflection, it can however provide ways to update the application at run-time.
Here is a reference to an awesome paper about class loader, and there usage:
I won't expand on whether this is good or bad, because it was not your question, but I think it's great to have support for run-time software evolution -- too bad that JSR-117 never made it!
这通常是我很乐意将其留给基础设施的功能,因为它很难正确且容易出错。正如乔恩上面提到的,大多数应用程序不需要它,对于那些需要它的应用程序,基础设施是可用的。
如今,大多数应用程序服务器都允许热部署,同样,大多数应用程序服务器都是可嵌入的,并允许将它们剥离以删除不需要的功能。
如果主要用于开发,您应该查看 JRebel ,它透明地提供了此功能。我听说他们正在开发运行时解决方案,但我不知道它是否已准备好迎接黄金时段。
如果您确实有动力让它发挥作用,那么请考虑使用 OSGi。它有一个陡峭的学习曲线,但是一旦你掌握了它,它就能正确地完成大多数事情并且工作得很好。我发现 pax 工具 是一个很好的起点,但 eclipse 工具链也有很好的支持它。
This is typically the kind of functionality I gladly leave to infrastructure as it is difficult to get right and easy to get wrong. As Jon mentioned above, most applications do not need it and for those that need it infrastructure is available.
Most application servers allow hot deployment nowadays, and equally most application servers are embeddable and allow them to be stripped down to remove features you do not need.
If it mainly for development, you should look a JRebel which provides this functionality transparently. I've heard they are working on a runtime solution, but I do not know if it is ready for primetime yet.
If you are really motivated to get this to work, then consider using OSGi. It has a steep learning curve, but once you grok it, it does most things right and works very well. I found the pax tools a good starting point but the eclipse toolchain also has good support for it.