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

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

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

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

  • JRebel的
  • 动态代码演进虚拟机(DCEVM)
  • Fakereplace
  • Apache Commons Java编译器Interace(JCI)FileAlterationMonitor(FAM)
  • AgentSmith
  • Feenix
  • 玩框架
  • JBoss / WildFly
  • OSGi的

那么有谁碰巧知道插件之间的差异是什么? 还有哪个插件最直观易用?

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

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

为了回答这个问题,我首先要提请你注意这样一个事实:你列出的名字之间的一个主要区别是:有些解决方案要求你改变应用程序设计,有些则不需要。

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

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

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

JRebelFakereplaceDCEVM – 那些人不关心编程模型。 但差异很大:

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

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

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

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

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

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

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

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