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