2010-11-04 31 views
4

我們經常從我們的Windows用戶可以得到以下堆棧跟蹤:如何檢測JVM是否升級而不重新啓動(在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的異常,這正是我們現在所做的。

我們希望有一種方法來檢查啓動時是否處於升級後需要重新引導的狀態,可以通過直接引發此異常並捕獲它或進行其他檢查。 (目前,我們不知道甚至觸發了這個......)有人知道我們可能會怎麼做嗎?

+0

是否在執行任何代碼之前異常發生的呢? – 2010-11-04 22:16:53

+0

@Grzegorz:好問題。我不知道,我沒有Windows機器來測試它。 – uckelman 2010-11-05 10:18:09

回答

2

恐怕你運氣不好。可能有一個註冊表項讓操作系統知道它需要重新啓動,但只有在安裝程序需要時纔會被設置。唯一的另一個例外是,如果有使用DLL的代碼,否則將由安裝程序取代。安裝過程將觸發操作系統的「需要重新啓動以完成」對話框。

我還沒有Java自動更新要求我重新啓動我的機器。如果操作系統從未處於「需要重新啓動」狀態,那麼您無需查找和檢查。你能做的最好的是捕捉異常並顯示一個很好的錯誤信息。我會把這個問題作爲Oracle的一個bug報告(man很難習慣這個)。也許未來的更新會表現得很好。

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 

} 
+0

這會在任何Java更新後第一次拋出,而不是僅在之後沒有重新啓動之後拋出,而且如果這是我們的應用第一次運行,您也無法檢測是否有更新但不重新啓動。 – uckelman 2010-11-05 12:22:26

+0

你是對的。抱歉。 – 2010-11-05 12:29:37

+0

但是如果您將這些信息與操作系統正常運行時間結合在一起呢?也就是說,讓我們將最新的應用程序的開始時間與當前的JVM版本一起存儲。然後在啓動時,我們也要檢查系統正常運行時間。 – 2010-11-05 22:00:56

相關問題