25

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

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

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

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

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

4

2 回答 2

36

免责声明: 我参与了 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 代码更改的支持要少得多(我假设),并且支持的框架的数量也不那么令人印象深刻。

Fenix可以做的与 Java Instrumentation API 允许的一样多。这基本上意味着它并没有真正在 JVM 的标准 HotSwap 之上增加价值。AgentSmith也一样

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

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

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

于 2013-07-14T18:56:03.917 回答
2

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

于 2015-01-30T11:54:08.343 回答