免责声明:我参与了JRebel的开发,因此我的答案可能有一点偏见,但我会尽力解释。
为了回答这个问题,我首先想要引起你的注意的是:你列出的这些名称之间的一个主要区别是:有些解决方案需要你改变应用程序设计,而其他方案则不需要。
模块化解决方案,例如OSGi或JBoss模块,如果你遵循正确的路径并对应用程序进行模块化,则提供了好处。否则,如果您部署一个单独的模块,则基本上意味着您正在重新启动/重新部署整个应用程序,从而削弱了此方法所获得的任何好处。
Play Framework实际上是一个全栈框架,具有热部署功能。这些功能取决于您使用的框架版本。但是,与模块化一样,该框架强制执行某种编程模型。
Apache Commons JCI并不是真正用于热更新代码的解决方案。据我所知,它只是通过新的类加载器编译和加载类。这也涉及更改应用程序代码,就像上面提到的情况一样。我不确定这是好还是坏。缺点是您几乎无法通过这种方式与生态系统进行广泛的集成。这种方法对于一个自制框架相当可行,可以利用此功能。我个人更喜欢使用Groovy、 JRuby或JavaScript等脚本语言来实现相同的功能。例如,类似这样的。
JRebel、Fakereplace和DCEVM - 这些工具不关心编程模型。但它们之间的区别很大:
DCEVM补丁了JVM,并旨在提供完整的热交换解决方案,它确实做到了。
JRebel是一个Java代理(通过-javaagent VM参数连接),它会对应用程序代码进行仪器化,并通过版本控制加载新版本的类。JRebel的主要价值在于,它提供灵活的配置以及大量特定于框架的集成,因此您不仅可以仅热交换Java类,还可以添加和自动装配Spring应用程序上下文中的新bean,实时添加新的EJBs和Struts操作等。
Fakereplace也是一种仪器化代理,像JRebel一样,但它对Java代码更改的支持要少得多(我假设),并且支持的框架数量也不那么令人印象深刻。
Feenix可以做到Java Instrumentation API允许其做的事情。这基本上意味着它并没有真正增加除JVM标准热交换之外的价值。同样适用于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 将重新加载编译后的类。