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

时间:2013-07-02 07:30:12

标签: java dynamic plugins classloader hotswap

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

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

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

所以有人碰巧知道插件之间的差异是什么?还有哪个插件是直观使用的?

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

2 个答案:

答案 0 :(得分:31)

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

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

模块化解决方案,如 OSGi JBoss模块,如果您遵循正确的路径并模块化您的应用程序,则会带来好处。否则,如果部署一个silo bundle,它基本上意味着您正在重新启动/重新部署整个应用程序,从而减少了从此方法中获得的任何好处。

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

Apache Commons JCI 并不是热门更新代码的解决方案。 AFAIK,它只是通过新的类加载器编译和加载类。这也涉及改变应用程序代码,如上所述。我不确定它是好还是坏。缺点是你几乎不能以这种方式与生态系统进行任何广泛的整合。对于使用此功能的自制框架,此方法相当可行。我自己,我宁愿使用像Groovy,JRuby或JavaScript这样的脚本语言来实现同样的目标。比如this之类的东西。

JRebel Fakereplace DCEVM - 这些人并不关心编程模型。但差别很大:

DCEVM 修补JVM,其目标是提供完整的热交换解决方案。

JRebel 是一个java代理(与-javaagent VM参数挂钩),用于检测应用程序代码并通过对其进行版本控制来加载新版本的类。 JRebel的主要价值在于它提供了灵活的配置以及huge amount of framework specific integrations,因此您可以做的不仅仅是java类的热交换。例如,在Spring应用程序上下文中添加和自动装配新bean,动态添加新EJB,以及新的Struts操作等。

Fakereplace 也是一个仪表代理,如 JRebel ,但它对Java代码更改的支持要少得多(我假设)并且支持的框架数量不多令人印象深刻。

Feenix 可以像Java Instrumentation API允许的那样做。这基本上意味着它并没有真正在JVM的标准HotSwap之上增加价值。对于 AgentSmith

也是如此

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

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

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

答案 1 :(得分:2)

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