Question

We frequently get the following stack trace from our Windows users:

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. Apparently upgrading Java requires (like everything else on Windows) the machine to be rebooted to get things back to a usable state.

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.

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?

Was it helpful?

Solution

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. The only other exception is if there is code using a DLL that would otherwise be replaced by the installer. 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. 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). Maybe future updates will behave properly.

OTHER TIPS

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. 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. 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. 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

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top