【发布时间】:2014-01-08 22:54:05
【问题描述】:
我有两个 jar 文件。 one.jar 包含启动进程的 main 方法,其他 two.jar 仅包含类文件。
在 One.jar 中,我在其清单类路径中引用了 two.jar。
One.jar 包含使用 Class.forName() 动态加载类的机制
我想一生只部署一次 One.jar。不会对其进行任何更改。
变化只会在 two.jar 中发生
我想用更新的 two.jar 热交换 two.jar。我也看过其他关于热插拔的帖子,比如 OSGi、ANT 的热插拔,但对我没有任何帮助。
经过一番研究发现 JRebel 确实做得更好,但我真的不知道如何将它与这些 jar 集成?我被困在这个问题上将近 2 天。只需几个步骤的信息即可完成此操作。请有人帮助我...这对我来说真的很重要...谢谢
【问题讨论】:
-
只需将 jar 放入预期的目录即可。如果你真的只是加载类,如果 jar 在你的类路径中,它会找到类。除非您的程序 24/7 全天候运行,否则这里不需要任何花哨的东西,因为那样它就不会从 jar 中释放类。
-
要替换一个类定义,你需要有你自己的类加载器来读取two.jar。然后,您丢弃该类加载器以摆脱内存中的旧 jar(及其所有对象)并创建一个新 jar 来读取新 jar。
-
@SnakeDoc 我没有在 Java 7 下尝试过这个,但是在下面的 Java 6 中,JVM 锁定了文件,使得替换它们变得困难......另外,JVM 怎么知道 Jars 有被替换?
-
编辑:哎呀,想法@MadProgrammer 是 OP!你正在编写一个 24/7 运行的程序吗?如果 JVM 终止(程序结束),那么 jars/classes 应该总是被释放。如果您的程序 24/7 运行(如应用程序服务器等),那么您将需要更强大的工业实力,例如 OSGi 或 JBoss/Glassfish 等。但这些都是大型重型 Java EE 容器,如果您的程序不是这种类型的,为此添加所有开销是没有意义的。
-
@MadProgrammer 对,这就是我的建议,只要应用程序不需要 24/7 全天候运行(比如一些维护期等)。显然是一个低技术的解决方案。另一种方法是实现一个“暂存”目录,将您的新 jar 放入该目录,并让文件夹观察服务每隔一段时间扫描该目录,如果找到一个 jar,则卸载前一个,将其删除,复制暂存area jar over,通过类加载器加载它。通过这种方式,您还可以将程序的“内部”与用户进一步隔离开来。