我想實現一個Java應用程序(服務器應用程序),可以從給定的URL下載新版本(.jar文件),然後在運行時自行更新。如何編寫可在運行時自行更新的Java應用程序?
這樣做的最好方法是什麼?它有可能嗎?
我猜應用程序可以下載一個新的.jar文件並啓動它。但我應該如何進行移交,例如知道新應用程序何時啓動然後退出。還是有更好的方法來做到這一點?
我想實現一個Java應用程序(服務器應用程序),可以從給定的URL下載新版本(.jar文件),然後在運行時自行更新。如何編寫可在運行時自行更新的Java應用程序?
這樣做的最好方法是什麼?它有可能嗎?
我猜應用程序可以下載一個新的.jar文件並啓動它。但我應該如何進行移交,例如知道新應用程序何時啓動然後退出。還是有更好的方法來做到這一點?
一個解決方案的基本結構如下:
有負責反覆加載最新版本的應用程序(如果需要),並啓動它的主循環。
該應用程序執行其操作,但會定期檢查下載URL。如果它檢測到新版本,它會退出到啓動器。
有很多方法可以實現這一點。例如:
的啓動可能是一個包裝腳本或二進制應用程序啓動一個新的JVM運行從被替換一個JAR文件的應用程序。
啓動器可能是一個Java應用程序,它爲新的JAR創建一個類加載器,加載一個入口點類並調用一些方法。如果你這樣做,你必須注意類加載器存儲泄漏,但這並不困難。 (你只需要確保從JAR裝載的類沒有對象可到達你重新啓動後)
外部包裝方法的優點是:
第二種方法需要兩個JAR,但具有以下優點:
「最好」的方式取決於您的具體要求。
還應當指出的是:
沒有與自動更新的安全隱患。一般而言,如果提供更新的服務器遭到入侵,或者提供更新的機制容易受到攻擊,則自動更新可能會導致客戶端的妥協。
將更新推送給客戶會對客戶造成損害,這可能會帶來法律風險,並且會對您的業務聲譽構成風險。
如果你能找到一種方法,以避免重新發明輪子,那將是一件好事。請參閱其他答案以獲取建議。
這並不一定是最好的方式,但它可能爲你工作。
您可以編寫一個應用程序引導(ALA魔獸世界啓動,如果你玩過WOW)。該引導程序負責檢查更新。
這樣你就不必擔心迫使你的應用程序的退出。
如果您的應用程序是基於Web的,如果它是重要的是他們有一個最新的客戶端,那麼你還可以做版本檢查應用程序運行時。您可以在執行與服務器的正常通信(部分或全部呼叫)或兩者兼而有之的情況下,每隔一段時間執行一次。
對於一個產品,我最近的工作,我們做了版本檢查一經推出(不啓動捆紮機應用程序,但主窗口出現之前),以及通話期間到服務器。當客戶端過時時,我們依靠用戶手動退出,但禁止對服務器進行任何操作。
請注意,我不知道,如果你把你的主窗口之前,Java可以調用UI代碼。我們正在使用C#/ WPF。
謝謝,這是一個很好的方式來做到這一點。但它是一個服務器應用程序,所以沒有用戶可以採取一些措施。而且我更喜歡它只是一個jar文件,所以用戶easyli可以下載一個jar並在開始時啓動它,但在此之後,我希望沒有用戶交互。 – Jonas 2010-10-23 04:28:45
當你說「服務器應用程序」時,你的意思是它是在登錄時直接在服務器上運行的應用程序嗎? – 2010-10-23 04:31:15
@Jonas:我不太瞭解.jar文件如何工作,所以我不能在那裏提供很多服務。我可以理解你是否更喜歡Java特有的答案。希望這可以讓你思考,至少:) – 2010-10-23 04:32:29
我寫了一個Java應用程序,可以在運行時加載插件,並立即開始使用它們,通過的jEdit類似的機制啓發。 jEdit是開源的,所以你可以選擇看看它是如何工作的。
解決方案使用自定義ClassLoader從jar中加載文件。一旦它們被加載,你可以從新的jar中調用一些方法,它將作爲它的main
方法。然後棘手的部分是確保你擺脫所有對舊代碼的引用,以便它可以被垃圾回收。我不是那方面的專家,我已經完成了工作,但並不容易。
我不瞭解Java,但在C#中,可以使用AppDomains顯式卸載代碼。也許在Java中有類似的概念。 – 2010-10-23 04:42:21
+1。好建議 – 2010-10-23 04:44:45
謝謝,這似乎是要走的路。在[ClassLoader]的JavaDoc中有一個'NetworkClassLoader'的示例(http://download.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html) – Jonas 2010-10-23 04:46:26
你的第二種方式似乎是一個有趣的設計。 – Jonas 2010-10-23 20:08:28
如果您在使用Equinox插件構建應用程序,你可以使用P2 Provisioning System得到一個現成的解決了這個問題。這將需要服務器在更新後自行重啓。
這是一個已知的問題,我建議不要重新發明輪子 - 不要編寫自己的黑客,只是使用其他人已經完成的操作。你需要
兩種情況考慮:
的應用程式必須自我更新,並保持更新(服務器應用,嵌入式應用程序)時甚至跑步。使用OSGi:Bundles或Equinox p2。
應用程序是一個桌面應用程序,並有一個安裝程序。有許多更新選項的安裝程序。檢查installers list。
我目前正在開發一個JAVA Linux守護進程,並且還需要實現自動更新機制。我想限制我的應用程序到一個jar文件,並提出了一個簡單的解決方案:
在更新本身中打包updater應用程序。
應用:當應用程序檢測到一個較新的版本,它具有以下功能:
ApplicationUpdater:當更新運行它具有下列功能:
希望它可以幫助別人。
你看過Java Web Start嗎?它不會在運行時更新自己,但我相信(需要重新啓動),因爲您可能需要查看OSGi。 – Thilo 2010-10-23 04:29:26
@Thilo:我認爲從給定的url下載文件很容易,然後從正在運行的jar文件中使用linux命令啓動它。 – Jonas 2010-10-23 04:32:37
Java WebStart API的設計使其在運行時無法更新。不幸。 – 2010-10-23 08:03:34