如何在不重新启动的情况下检测JVM是否已升级(在Windows上)?

时间:2010-11-04 18:47:53

标签: java windows upgrade reboot

我们经常从Windows用户那里获得以下堆栈跟踪:

java.lang.UnsatisfiedLinkError: sun.awt.image.ImageRepresentation.setBytePixels(IIII[BIILsun/awt/image/ByteComponentRaster;I)V
    at sun.awt.image.ImageRepresentation.setBytePixels(Native Method)
    at sun.awt.image.ImageRepresentation.setPixels(Unknown Source)
    at sun.awt.image.ImageDecoder.setPixels(Unknown Source)
    at sun.awt.image.GifImageDecoder.sendPixels(Unknown Source)
    at sun.awt.image.GifImageDecoder.parseImage(Native Method)
    at sun.awt.image.GifImageDecoder.readImage(Unknown Source)
    at sun.awt.image.GifImageDecoder.produceImage(Unknown Source)
    at sun.awt.image.InputStreamImageSource.doFetch(Unknown Source)
    at sun.awt.image.ImageFetcher.fetchloop(Unknown Source)
    at sun.awt.image.ImageFetcher.run(Unknown Source)

当用户升级Java,然后尝试运行我们的应用程序而不首先重新启动时会发生这种情况。显然,升级Java需要(像Windows上的其他所有内容一样)重新启动计算机以使事物恢复到可用状态。

这不是我们可以捕获的异常,因为我们的代码都不在调用堆栈中。我们可以处理来自Thread.UncaughtExceptionHandler的异常,这就是我们现在正在做的事情。

我们希望有一种方法可以在启动时检查我们是否处于需要重新启动后的状态,直接导致此异常并捕获它,或进行其他检查。 (目前,我们还不知道甚至会触发这个......)有谁知道我们会怎么做呢?

2 个答案:

答案 0 :(得分:2)

我担心你运气不好。可能有一个注册表项让操作系统知道它需要重新启动,但只有在安装程序需要时才会设置。唯一的另一个例外是,如果存在使用DLL的代码,否则将由安装程序替换。安装过程将触发操作系统中的“需要重启以完成”对话框。

我还没有Java自动更新要求我重启我的机器。如果操作系统永远不会处于“需要重启”状态,则无需查找和检查。您可以做的最好的事情是捕获异常并显示一个很好的错误消息。我会把这个问题报告给Oracle作为一个错误(男人很难习惯)。也许未来的更新会表现得很好。

答案 1 :(得分:0)

如果您有保证能够在异常发生之前调用某些代码,我建议您考虑进行手动java版本检查。您永远不知道上次升级是否会导致此类崩溃,但您始终可以检查自上次执行以来Java版本是否已更改。让我们以一种简单的方式存储它。

然后,在每次启动期间,如果Java版本已更改,您将显示信息'Java已更新且我的应用程序可能表现不正确。建议重新启动'和/或停止继续。

类似的东西:

public static void main(String[] argv) {
  String lastJVM = retrieveJVMversionFromLastExecution();
  String currentJVM = System.getProperty("java.version");
  if (!currentJVM.equals(lastJVM)) {
     throw new RuntimeException("New JVM. Please reboot");
  }  else {
     storeJVMversionPersistently(currentJVM);
  }     

  // ... your normal operation

}