特定のURLから新しいバージョン(.jarファイル)をダウンロードして、実行時に自身を更新できるJavaアプリケーション(サーバーアプリケーション)を実装したいと思います。
これを行う最善の方法は何ですか?それは可能ですか?
アプリケーションが新しい.jarファイルをダウンロードして開始できると思います。しかし、どのようにしてハンドオーバーを実行すればよいでしょうか。たとえば、新しいアプリケーションがいつ開始されてから終了するかを知っています。またはこれを行うより良い方法はありますか?
特定のURLから新しいバージョン(.jarファイル)をダウンロードして、実行時に自身を更新できるJavaアプリケーション(サーバーアプリケーション)を実装したいと思います。
これを行う最善の方法は何ですか?それは可能ですか?
アプリケーションが新しい.jarファイルをダウンロードして開始できると思います。しかし、どのようにしてハンドオーバーを実行すればよいでしょうか。たとえば、新しいアプリケーションがいつ開始されてから終了するかを知っています。またはこれを行うより良い方法はありますか?
回答:
ソリューションの基本的な構造は次のとおりです。
アプリの最新バージョン(必要な場合)を繰り返しロードして起動するメインループがあります。
アプリケーションは機能しますが、ダウンロードURLを定期的にチェックします。新しいバージョンを検出すると、終了してランチャーに戻ります。
これを実装する方法はいくつかあります。例えば:
ランチャーは、新しいJVMを起動して、置き換えられるJARファイルからアプリケーションを実行するラッパースクリプトまたはバイナリアプリケーションである可能性があります。
ランチャーは、新しいJARのクラスローダーを作成し、エントリーポイントクラスをロードして、そのクラスのメソッドを呼び出すJavaアプリケーションである可能性があります。このようにすると、クラスローダーのストレージリークを監視する必要がありますが、それは難しくありません。(再起動後、JARからロードされたクラスを持つオブジェクトにアクセスできないことを確認する必要があるだけです。)
外部ラッパーアプローチの利点は次のとおりです。
2番目のアプローチには2つのJARが必要ですが、次の利点があります。
「最良の」方法は、特定の要件によって異なります。
次の点にも注意してください。
自動更新にはセキュリティ上のリスクがあります。一般に、更新を提供するサーバーが危険にさらされている場合、または更新を提供するメカニズムが攻撃を受けやすい場合、自動更新はクライアントの危険につながる可能性があります。
クライアントに損傷を与える更新をクライアントにプッシュすると、法的リスクが発生し、ビジネスの評判にリスクが発生する可能性があります。
車輪の再発明を回避する方法を見つけることができれば、それは良いことです。提案については、他の回答を参照してください。
私は現在、JAVA Linuxデーモンを開発しており、自動更新メカニズムを実装する必要もありました。アプリケーションを1つのjarファイルに制限したかったので、簡単な解決策を考え出しました。
アップデート自体にアップデータアプリケーションをパックします。
アプリケーション:アプリケーションは、新しいバージョンを検出すると、次のことを行います。
ApplicationUpdater:アップデーターが実行されると、次のことを行います。
それが誰かを助けることを願っています。
これは既知の問題であり、ホイールを再発明しないことをお勧めします。独自のハックを作成せず、他の人がすでに行っていることを使用してください。
考慮する必要がある2つの状況:
アプリは自己更新可能で、更新中も実行し続ける必要があります(サーバーアプリ、埋め込みアプリ)。OSGi:BundlesまたはEquinox p2を使用してください。
アプリはデスクトップアプリで、インストーラーがあります。更新オプションを備えた多くのインストーラがあります。インストーラーのリストを確認してください。
実行時にプラグインをロードしてすぐに使用を開始できるJavaアプリケーションをjEditの同様のメカニズムに触発されて書きました。jEditはオープンソースであるため、動作を確認するオプションがあります。
ソリューションは、jarからファイルをロードするためにカスタムClassLoaderを使用します。それらがロードされると、そのmain
メソッドとして機能する新しいjarからいくつかのメソッドを呼び出すことができます。次に、トリッキーな部分は、古いコードへのすべての参照を削除して、ガベージコレクションを行えるようにすることです。私はその部分の専門家ではありません、私はそれを機能させましたが、それは簡単ではありませんでした。
これは必ずしも最良の方法ではありませんが、うまくいくかもしれません。
ブートストラップアプリケーションを作成できます(WoWをプレイしたことがある場合は、World of Warcraftランチャーを使用します)。そのブートストラップは、更新のチェックを担当します。
これにより、アプリケーションの強制終了を心配する必要がなくなります。
アプリケーションがWebベースであり、クライアントに最新のクライアントがあることが重要な場合は、アプリケーションの実行中にバージョンチェックを行うこともできます。サーバーとの通常の通信(一部またはすべての呼び出し)、またはその両方を実行している間、それらを定期的に実行できます。
私が最近取り組んだ製品については、起動時(ブートストラッパーアプリなしで、メインウィンドウが表示される前)、およびサーバーへの呼び出し中にバージョンチェックを行いました。クライアントが古くなったとき、私たちはユーザーに手動で終了することを頼りにしましたが、サーバーに対するいかなるアクションも禁止しました。
メインウィンドウを表示する前にJavaがUIコードを呼び出すことができるかどうかはわかりません。私たちはC#/ WPFを使用していました。
Equinoxプラグインを使用してアプリケーションをビルドする場合、P2プロビジョニングシステムを使用して、この問題の既製のソリューションを入手できます。これには、更新後にサーバーを再起動する必要があります。