2010-11-04 13 views
4

Nous obtenons souvent la trace de la pile suivante de nos utilisateurs de Windows:Comment détecter si la JVM a été mise à niveau sans redémarrer (sous 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) 

Cela se produit lorsque l'utilisateur a mis à jour Java, et tente ensuite d'exécuter notre application sans redémarrer d'abord. Apparemment, la mise à niveau de Java nécessite (comme tout le reste sous Windows) que la machine soit redémarrée pour ramener les choses à un état utilisable.

Ce n'est pas une exception que nous pouvons attraper, car aucun de notre code n'est dans la pile d'appels. Nous pouvons gérer l'exception d'un Thread.UncaughtExceptionHandler, ce qui est ce que nous faisons maintenant. Nous aimerions plutôt avoir un moyen de vérifier au démarrage si nous sommes dans un état besoin de redémarrer après la mise à jour, soit en provoquant cette exception directement et en l'attrapant, soit en effectuant une autre vérification. (Actuellement, nous n'avons aucune idée de ce qui déclenche même cela ...) Est-ce que quelqu'un sait comment nous pourrions nous y prendre?

+0

Est-ce que l'exception arrive avant que votre code est exécuté? –

+0

@Grzegorz: Bonne question. Je ne sais pas, et je n'ai pas de machine Windows pour le tester. – uckelman

Répondre

2

Je crains que vous n'ayez pas de chance. Il peut y avoir une entrée de registre pour faire savoir au système d'exploitation qu'il doit redémarrer, mais cela ne sera défini que si le programme d'installation l'exige. La seule autre exception est s'il y a du code utilisant une DLL qui serait sinon remplacée par le programme d'installation. Le processus d'installation déclencherait la boîte de dialogue «doit redémarrer pour terminer» à partir du système d'exploitation.

Je n'ai pas encore de mise à jour automatique Java et je dois redémarrer mon ordinateur. Si le système d'exploitation n'est jamais dans l'état "require restart", il n'y a rien à chercher et à inspecter. Le mieux que vous puissiez faire est d'attraper l'exception et d'afficher un message d'erreur sympa. Je signalerais ce problème comme un bogue à Oracle (homme, il sera difficile de s'y habituer). Peut-être que les futures mises à jour se comporteront correctement.

0

Si vous avez la garantie de pouvoir appeler du code avant que l'exception ne se produise, je vous suggérerais d'envisager de faire une vérification manuelle de la version java. Vous ne savez jamais si la dernière mise à niveau provoquerait un tel plantage, mais vous pouvez toujours vérifier si la version de Java a changé depuis la dernière exécution. Mettons-le stocké quelque part d'une manière simple. Puis, au cours de chaque démarrage, si la version Java a changé, vous afficheriez des informations: «Java a été mis à jour et mon application peut ne pas fonctionner correctement. Redémarrage est suggéré 'et/ou cesse de continuer.

Quelque chose comme:

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 

} 
+0

Cela se produira la première fois après une mise à jour Java, et non après un redémarrage, et vous ne pourrez pas non plus détecter si une mise à jour a été effectuée ou non si c'est la première fois que l'application est lancée. – uckelman

+0

Vous avez absolument raison. Pardon. –

+0

Mais que se passe-t-il si vous avez combiné les informations avec le temps de fonctionnement du système d'exploitation? C'est-à-dire stockons la dernière heure de démarrage de votre application avec la version actuelle de la JVM. Ensuite, au démarrage, vérifions également le temps de fonctionnement du système. –