我有一个软件,包含在单个.jar中,它正在完成其工作但有时我需要快速推送错误修复,必须在中心位置替换.jar文件,不幸的是,如果当前正在执行这个jar文件,如果我替换它然后崩溃与“类未找到”错误。我认为一旦执行了一个jar文件,JVM就会将它缓存在内存中并且不会从磁盘上进行任何读取,但显然情况并非如此,如何(如果可能的话)可以解决这个问题?
修改
该应用程序不是基于Web的。这是正常的Java SE。
答案 0 :(得分:3)
JAR文件不会像其他共享对象库一样批量加载到内存中。它们的类是根据需求加载到内存中的,所以如果你删除一个JAR文件并且需要进行类查找,那么类加载器的文件句柄将是无效的(因为它引用的打开文件现在已经消失了)你会得到错误。
操作系统管理文件句柄,因此用新副本替换打开的文件不会欺骗任何人。您需要先关闭文件,这通常只能通过垃圾收集类加载器来完成。如果您正在使用系统类加载器,那么这意味着关闭JVM。
人们已经编写了用于创建自定义类加载器的框架,这些加载器可以独立于系统类加载器进行处理;但是,这确实使类加载变得复杂。虽然它可以完成你所要求的,但是如果不重构你现有的程序来适应框架类加载器中的类的查找(并且随着时间的推移容纳类加载器的损失和收益),它就不能这样做。
如果您想尝试这样的框架,请参阅Christian的帖子。如果您想更多地了解一个项目如何使用类加载器来满足其需求,请查看Apache的Tomcat,它将Web应用程序限制在自己的类加载器中。
通常,您可能会发现正确的答案实际上是在部署之前停止服务,并在部署之后启动它。
答案 1 :(得分:1)