2011-06-25 89 views
16

鑑於JVM中運行的JAR,可以卸載當前運行的JAR並將其從系統中刪除。下載一個新版本,並用最後一個Jar的相同名稱進行重命名,然後初始化新的Jar,從而在JVM內創建Jar的無縫更新。是否有可能指示JVM執行此操作?在運行時更新Jar甚至有可能嗎?在運行時更新JAR

回答

1

通常你不能這樣做,因爲這種行爲據我所知沒有正式定義。

但是,您可以使用jar文件創建類加載器您的官方類路徑,然後根據需要從中加載類。通過丟棄類加載器加載的類的所有實例,您可以刪除當前資源,然後在新的jar文件上實例化新的類加載器,然後加載新類並創建新對象。

這是相當複雜的,所以也許你會使jar成爲OSGi模塊並通過OSGi-loader調用你的程序?

1

您無法寫入正在運行的jar。沒有等同於寫入的getResourceInputStream。我想如果你嘗試使用FileOutputStream來編寫,就像JVM使用它一樣,你將無法刪除它,因爲系統會阻止它。

無論如何,仍然有可能在不同的罐子中提供不同模塊的更新。所以你可以想象有一個應用程序的主jar文件,可以通過一個小的獨立可運行jar文件更新包含更新。

也可以使用JNLP來自動和無縫更新應用程序。

服務器端應用程序也是向用戶隱藏更新的替代方法。

問候, 斯特凡

1

答案就在Java的類加載器。這些人從JARS或.class文件或byte[]值或URL或其他任何東西加載類。每當你訪問一個類時,你都隱式地使用一個類加載器來給你一個類的正確實例。

創建您所選擇的類加載器,並在需要類的「刷新」時切換類加載器。看看Thread.setContextClassLoader方法 - 這將改變一個Thread的類加載器。

定義您自己的類加載器非常直觀 - 只需劃分ClassLoader類並覆蓋它的findClass method即可。

18

下載新版本,並與上次罐的同名將其重命名 和 然後初始化新瓶,創建 的Jar的無縫更新 在JVM中...它甚至有可能到 在運行時更新Jar?

JAR文件不是'正在運行',JVM正在運行。您的JAR文件只包含使JVM執行有用工作的類信息(又稱字節代碼指令)。在大多數情況下,JVM實際上不會在您的JAR文件上放置系統鎖,因此您可以將該文件替換爲您的內容。

當然真正的問題是,一旦JVM加載你的JAR,它將會很高興地裝載它,並且不會再從JAR文件中讀取,無論你覆蓋多少次。這是默認的類加載器的行爲,不能改變 - 但正如其他人指出的 - 你不必使用默認的類加載器。爲了從文件系統加載更新的JARS,您可以實現自己的,與Web應用程序服務器使用的類似。警惕 - 雖然定義你自己的類加載器被認爲是一個'壞想法',除非你真的知道你在做什麼。你可以閱讀更多here和​​。

+1

我們在加載類之後更新jar的問題,我們最終得到了NoClassDefined錯誤。我猜測所請求的類沒有被加載,並且當JVM試圖這樣做時,該jar足夠不同以至於「損壞」。 –

+3

僅供參考,Windows 7確實鎖定了罐子 – etherous

+0

默認的classloader是否在開始時加載每個類?你可以站點的來源? – Cybermonk

17

這是我以前看過很多次的事情(也是我自己做過的)。我撰寫了一些可能出現的問題/解決方案。

  • 如果您覆蓋稍後將使用的JAR文件,JVM將因轉儲而崩潰。
    • 通過後,我的意思是類相當延遲加載,有些可能只在程序的生命加載後
    • JVM已打開的句柄的JAR文件和lib文件將失敗,因爲JAR和指針變成錯誤
    • 通過預先加載JAR文件中的所有類和資源可以降低此概率
    • 如果您有自定義類加載器,則可以自行關閉這些句柄。
  • 您將需要了解如何完成類加載。更好的是在控制。
    • 自定義類加載器,將創建每個JAR一個類加載器和管理版本
    • 知道你的應用程序如何使用類加載器以及它如何作用於新JAR(例如檢查,當你覆蓋一個WAR歸檔什麼的Tomcat一樣)
  • 在Windows上,您的JAR文件將被鎖定,您無法覆蓋它們。如果你在控制中,那麼你可以在使用後解鎖它們(關閉它們)。對於第三方系統,您必須找到相應的標誌。例如,您可以在Tomcat上下文配置中檢查antiJARLocking
  • 總是更好,以避免覆蓋相同的文件,而有一些版本回事

總之有一些您可能會遇到當你想實現JAR重新裝入許多問題。幸運的是,如何將風險降至最低。最安全的方法是做類似的事情來獲得相同的效果。 Cleanest是自定義類加載器和JAR文件版本控制。

+0

對我來說,如果覆蓋JAR文件,它不會崩潰,它稍後想要使用需要加載的方法。我的(多線程)程序只是掛在100%的CPU上,花了我很多時間才發現重建JAR可能是原因。 –