简体   繁体   English

如何检测JVM是否已升级而没有重新引导(在Windows上)?

[英]How to detect whether the JVM has been upgraded without rebooting (on Windows)?

We frequently get the following stack trace from our Windows users: 我们经常从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)

This happens when the user has upgraded Java, and then tries to run our app without rebooting first. 当用户升级Java,然后尝试运行我们的应用程序而不先重新启动时,就会发生这种情况。 Apparently upgrading Java requires (like everything else on Windows) the machine to be rebooted to get things back to a usable state. 显然,升级Java需要重新启动计算机(就像Windows上的其他所有工具一样),以使事情恢复到可用状态。

This isn't an exception we can catch, since none of our code is in the call stack. 这不是我们可以捕获的异常,因为我们的代码都不在调用堆栈中。 We can handle the exception from a Thread.UncaughtExceptionHandler , which is what we're doing now. 我们可以Thread.UncaughtExceptionHandler处理异常,这是我们现在正在做的。

We'd like instead to have a way to check at startup whether we're in a need-to-reboot-after-upgrade state, either by causing this exception directly and catching it, or doing some other check. 相反,我们希望有一种方法可以在启动时检查是否处于升级后需要重新引导的状态,方法是直接导致此异常并捕获它,或者进行其他检查。 (Presently, we have no idea what even triggers this...) Does anyone know how we might go about that? (目前,我们不知道是什么触发了这个……)有人知道我们可能会怎么做吗?

I'm afraid you are out of luck. 恐怕你不走运。 There may be a registry entry to let the OS know that it needs to reboot, but that only gets set if the installer requires it. 可能会有一个注册表项让OS知道它需要重新启动,但是只有在安装程序需要时才设置。 The only other exception is if there is code using a DLL that would otherwise be replaced by the installer. 唯一的其他例外是​​如果存在使用DLL的代码,否则该代码将被安装程序替换。 The installation process would trigger the "needs reboot to complete" dialog box from the OS. 安装过程将从操作系统触发“需要重新启动才能完成”对话框。

I have yet to have a Java automatic update require me to reboot my machine. 我尚未进行Java自动更新,要求我重新启动计算机。 If the OS is never in a "require reboot" state, there is nothing for you to find and inspect. 如果操作系统从未处于“需要重新启动”状态,则没有任何内容可供您查找和检查。 The best you can do is catch the exception and display a nice error message. 您能做的最好的就是捕获异常并显示一条不错的错误消息。 I would report this issue as a bug to Oracle (man it'll be hard getting used to that). 我会将这个问题作为错误报告给Oracle(否则很难适应)。 Maybe future updates will behave properly. 也许将来的更新将正常运行。

If you have a guarantee to be able to call some code before the exception happens, I would suggest considering doing manual java version check. 如果您保证能够在异常发生之前调用某些代码,则建议考虑进行手动Java版本检查。 You never know if the last upgrade would cause such a crash, but you can always check if the Java version has changed since last execution. 您永远不会知道上次升级是否会导致此类崩溃,但是您始终可以检查自上次执行以来Java版本是否已更改。 Let's have it stored somewhere in a simple way. 让我们以一种简单的方式将其存储在某个地方。

Then, during each startup if the Java version has changed, you would display information 'Java has been updated and my application may behave improperly. 然后,在每次启动期间,如果Java版本已更改,您将显示信息“ Java已更新,并且我的应用程序可能无法正常运行。 Reboot is suggested' and/or cease to continue. 建议重新启动”和/或停止继续。

Something like: 就像是:

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM