用于热类重装的各种Java插件之间有什么区别,哪一个最直观?

2022-09-01 18:55:05

我目前正在尝试在Java应用程序中实现热类重新加载,但是有太多的插件可供选择,我无法在这些选项之间找到很好的比较。此外,插件的网站也不是很清楚确切的功能是什么以及如何使用它们。

还可以选择进行自定义热类重新加载ClassLoader,但是如果已经有这么多插件可以完成这项工作,我觉得这类似于“重新发明轮子”。其他人同意这一点吗?

我发现的Java插件我认为可以完成这项工作:

那么有没有人碰巧知道插件之间的区别是什么?还有哪个插件使用起来最直观

作为旁注:我实际上想做的是重新加载我的java应用程序的.jar文件依赖项。我有一些java代码,它们经常被自动重新编译,然后转换为.jar文件。它是我的java应用程序的依赖项,我的应用程序每次都需要使用此.jar文件的最新版本。


答案 1

免责声明:我参与了JRebel的开发,因此我的答案可能看起来有点偏颇,但我会尽力解释。

为了回答这个问题,我首先想提请您注意这样一个事实,即您列出的名称之间的一个主要区别是:某些解决方案要求您更改应用程序设计,而其他解决方案则不需要。

模块化解决方案,如 OSGiJBoss 模块,如果您遵循正确的路径并模块化您的应用程序,就会带来好处。否则,如果您部署一个思洛存储器捆绑包,这基本上意味着您正在重新启动/重新部署整个应用程序,从而减少从此方法中获得的任何好处。

Play Framework实际上是一个具有热部署功能的全栈框架。这些功能因您使用的框架版本而异。但同样,与模块化的故事相同 - 框架强制执行某种编程模型。

Apache Commons JCI并不是热更新代码的真正解决方案。AFAIK,它只是通过新的类装入器编译和装入类。这也涉及更改应用程序代码,如上述情况所示。我真的不确定它是好是坏。缺点是,您几乎无法以这种方式与生态系统进行任何广泛的集成。对于利用此功能的自制框架,这种方法是相当可行的。我自己,我宁愿使用像Groovy,JRuby或JavaScript这样的脚本语言来实现同样的目标。例如,类似这样的东西

JRebelFakereplaceDCEVM - 那些家伙不关心编程模型。但差异相当大:

DCEVM对JVM进行了修补,其目标是提供完整的热插拔解决方案,它确实做到了。

JRebel 是一个 java 代理(与 -javaagent VM 参数挂钩),它检测应用程序代码并通过对类进行版本控制来加载新版本的类。JRebel的主要价值在于它提供了灵活的配置以及大量特定于框架的集成,因此您可以做的不仅仅是java类的热插拔。例如,在Spring应用程序上下文中添加和自动连接新Bean,动态添加新的EJB以及新的Struts操作等。

Fakereplace也是一个检测代理,就像JRebel一样,但它对Java代码更改的支持要少得多(我假设),并且支持的框架数量也没有那么令人印象深刻。

Feenix可以做Java Instrumentation API允许的尽可能多的事情。这基本上意味着它并没有真正在JVM的标准HotSwap之上增加价值。与特工史密斯相同

更新:这个答案促使Feenix的作者提出了一个新版本 - Feenix 2.0,类似于JRebel处理类的方式。但正如作者自己所说-Feenix仍然远远不如JRebel。还有一些类似的解决方案,如HotswapAgentSpring Loaded - 这些工具也提供类似的功能,但以自己的方式受到限制。

现在谈谈你的具体问题,如何使用JRebel解决它:

应用程序的每个模块都应该有自己的配置文件,rebel.xml。通过模块,我们的意思是,EAR,WAR或WEB-INF / lib中的任何JAR依赖项(如您的情况)或服务器特定的库。带有的配置文件指向编译类所在的目录,JRebel 将直接从该位置加载类。这一切都意味着,一旦对 Java 类进行了更改,就不需要组装整个 JAR。相反,您可以进行更改并编译源代码(利用 IDE 而不是构建脚本)。一旦在应用程序代码中调用编译的类,JRebel 就会重新加载该类。


答案 2

有一个新的孩子,RelProxy,它是开源的,不像JRebel那样先进,但它可以用来在运行时自由更改代码的子集并重新加载它,几乎没有性能损失,如果你愿意,也不需要在开发和生产中重新加载上下文(没有会话丢失)。


推荐