4

我们经常从我们的 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 上的所有其他东西一样)重新启动机器以使事情恢复到可用状态。

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

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

4

2 回答 2

2

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

我还没有 Java 自动更新需要我重新启动我的机器。如果操作系统从不处于“需要重新启动”状态,则您无需查找和检查任何内容。您能做的最好的事情就是捕获异常并显示一个很好的错误消息。我会将这个问题作为一个错误报告给 Oracle(伙计,这很难习惯)。也许未来的更新会正常运行。

于 2010-11-04T22:09:57.103 回答
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

}
于 2010-11-05T10:51:14.307 回答