【问题标题】:Java program crashes if underlying jar is replaced如果底层 jar 被替换,Java 程序会崩溃
【发布时间】:2012-05-31 05:46:01
【问题描述】:

我有一个软件,包含在一个 .jar 中,它正在执行它的工作,但有时我需要快速推送一个错误修复,需要在中心位置替换 .jar 文件,不幸的是,如果当前正在运行执行如果我替换这个 jar 文件,它会因“找不到类”错误而崩溃。我认为一旦执行了 jar 文件,JVM 会将其缓存在内存中并且不会从磁盘读取任何内容,但显然情况并非如此,如何(如果可能的话)解决这个问题?

编辑:

该应用程序不是基于网络的。这是普通的 Java SE。

【问题讨论】:

  • 为什么不停止执行,更换jar,然后重启呢?
  • 然后你可以写一个脚本。将更新的 jar 放到某个文件夹中,运行停止它的脚本,复制新的 jar,然后再次启动它。
  • time is money :) - 如果您的程序没有崩溃,则不会。
  • 这个 SO 问题可能会为您解答一些问题。 stackoverflow.com/questions/660437/…

标签: java continuous-deployment


【解决方案1】:

JAR 文件不会像其他共享对象库那样批量加载到内存中。他们的类是按需加载到内存中的,所以如果你删除了一个 JAR 文件并且需要进行类查找,那么类加载器的文件句柄将是无效的(因为它引用的打开文件现在已经消失了),你会得到一个错误。

操作系统管理文件句柄,因此用新副本替换打开的文件不会欺骗任何人。您需要先关闭文件,这通常只能通过垃圾收集类加载器来完成。如果您使用的是系统类加载器,那么这意味着关闭 JVM。

人们已经编写了框架来创建可以独立于系统类加载器进行处理的自定义类加载器;但是,这确实使类加载复杂化。虽然它可以完成您的要求,但如果不重新构建现有程序以适应在框架的类加载器中查找类(并适应类加载器随时间的损失和获得),它就无法做到。

如果您想尝试这样的框架,请参阅 Christian 的帖子。如果您想了解更多关于一个项目如何使用类加载器来满足其需求的信息,请查看 Apache 的 Tomcat,它将 Web 应用程序限制在自己的类加载器中。

通常您可能会发现正确的答案确实是在部署之前停止服务,并在部署后启动它。

【讨论】:

    【解决方案2】:

    我能想到的唯一两种可能性是使用JRebelOSGi

    【讨论】:

      猜你喜欢
      • 2011-02-21
      • 1970-01-01
      • 2015-09-26
      • 1970-01-01
      • 1970-01-01
      • 2016-09-19
      • 2011-01-31
      • 1970-01-01
      相关资源
      最近更新 更多