簡體   English   中英

更換jar文件時無法在jar文件中加載資源

[英]Failed to load resources in jar file when jar file is replaced

我遇到java.util.zip.ZipException:存儲的塊長度無效。

堆棧跟蹤如下:

Caused by: java.util.zip.ZipException: invalid stored block lengths
at java.util.zip.InflaterInputStream.read(Unknown Source)
at java.io.FilterInputStream.read(Unknown Source)
at java.io.FilterInputStream.read(Unknown Source)
at java.util.Properties$LineReader.readLine(Unknown Source)
at java.util.Properties.load0(Unknown Source)
at java.util.Properties.load(Unknown Source)

當我的項目嘗試升級時會發生這種情況。 升級邏輯是用新的jar文件替換舊的jar文件,JVM仍然在運行。

jar文件(jarA.jar)包含屬性文件,屬性文件記錄一些完整的類名。 這些類名將用於通過反射創建實例。 升級邏輯嘗試使用SystemClassLoader.getResourceAsStream()加載屬性文件。

如果jar文件(jarA.jar)被替換為新文件,並且屬性的內容發生了更改,則會發生此異常。 似乎SystemClassLoader無法正確加載屬性。

該項目由java1.4編譯,並在jre1.7上運行,Os是Windows。

有沒有人可以解釋為什么SystemClassLoader在屬性存在時無法加載? 我感謝您的幫助。

通常只有在第一次需要時才從jar文件中讀取類。

當JVM運行時替換jar文件時,JVM所具有的文件InputStream已經過時了。 在這種情況下,如果未更改JAR文件的內容,則可以從jar中讀取類。 如果替換的jar具有與舊jar不同的內容,則obsolte InputStream將嘗試讀取其已知的位置。 但是,由於conent已更改,因此可能無法讀取文件。

因此這個例外

類重新加載通常是通過丟棄舊的類加載器並為類的更新版本創建新的類加載器來完成的。 據我所知,無法在同一個類加載器中重新加載更改的類。

重新加載屬性文件是另一個問題。 但是它不能包含在jar中,你必須監視文件的變化。 在這種情況下,您也不應該使用getResourceAsStream()。

如果要在替換jar文件后使用getResourceAsStream(String),則只需實現自己的方法ClassLoader.findResource(String)

public URL findResource(final String name) {
    // find URL (and cache it if necessary (Hashtable ?))
    // do not call super.findResource(String)
    return url; // in a jar: new URL("jar:jar-path!/" + name);
}

它將確保正確地重新加載任何資源(即使在jar中)。

(我仍然不確定,但是默認的類加載器似乎存儲了與第一個找到的URL的連接,它在替換源后失效,但在負責類的類加載器中保持不變)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM