これは概要ページです。詳細については、hotswapagent.org をご覧ください。
Java の無制限のランタイム クラスとリソースの再定義。
このプロジェクトの主な目標は、従来の「コードの変更 -> 再起動して待機... -> チェック」という開発サイクルの必要性を排除することでした。時間の経過とともに、この概念は Java エコシステム内の新しいパラダイムに進化し、実行中のアプリケーション内でのリアルタイム ソフトウェア開発を可能にしました。このアプローチは、Docker コンテナなどの制限された環境でも実現可能です。
IntelliJ ユーザーの場合は、IntelliJ HotSwapHelper プラグインを使用して HA と DCEVM のセットアップを簡素化できます。
ダウンロードしてインストールします:
Java 17/21 の場合:最新の JBR17 または JBR21 をダウンロードします。これらのバージョンには組み込みのホットスワップ エージェントが含まれていないため、 hotswap-agent.jar
lib/hotswap
フォルダーに手動でコピーする必要があります。最新のホットスワップ エージェントはここで見つけることができます。 lib/hotswap
フォルダー内のファイルの名前がhotswap-agent.jar
であり、ファイル名にバージョン番号が含まれていないことを確認します。
Java 11 の場合: HotswapAgent が統合された TravaJDK を使用し、代替 JDK としてインストールします。あるいは、TravaJDK には埋め込み HotswapAgent が含まれています。
Java 8 の場合: jdk8-dcevm を HotswapAgent とともに使用します。
ホットスワップエージェントモード:
dcevm-11.0.9
以降、HotswapAgent はデフォルトで無効になっています。次の 3 つのモードのいずれかで JVM オプションを使用して、HotswapAgent のサポートを有効にできます。
HotswapAgent=core
モードは、コア JVM プラグインを除き、追加のプラグインなしで動作するため、スキャンとクラス コピーのタスクが削減され、パフォーマンスが向上します。追加のプラグインを使用するには、 pom.xml
ファイルでそれらを Maven 依存関係として構成する必要があります。一方、 HotswapAgent=fatjar
モードにはデフォルトですべてのプラグインが含まれるため、アプリケーションの起動がわずかに遅くなる可能性があります。
-XX:HotswapAgent=fatjar
内部の fatjar HotswapAgent をアクティブ化します。
-XX:HotswapAgent=core
内部コア HotswapAgent をアクティブにします。
-XX:HotswapAgent=external
、HotswapAgent の JVM サポートを構成し、ユーザーが-javaagent:
オプションを使用して外部hotswap-agent.jar
を提供できるようにします。
3.起動:
Java17/21: オプション-XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar
指定してアプリケーションを起動し、高度なホットスワップ (dcevm) をオンにし、ホットスワップ エージェントの fatjar リリースを使用します。代替として、 fatjar
の代わりにcore
またはexternal
モードを使用できます。
Java11: ホットスワップ エージェントの fatjar リリースを使用するには、オプション-XX:HotswapAgent=fatjar
指定してアプリケーションを起動します。
Java8: オプション-XXaltjvm=dcevm -javaagent:hotswap-agent.jar
を指定してアプリケーションを起動し、基本的なセットアップを取得します。オプションで、 hotswap-agent.properties
アプリケーションに追加して、プラグインとエージェントの動作を構成できます。
3.アプリケーションを実行します。
アプリケーションをデバッグ モードで起動し、エージェントとプラグインが正しく初期化されていることを確認します。
HOTSWAP AGENT: 9:49:29.548 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent - unlimited runtime class redefinition. HOTSWAP AGENT: 9:49:29.725 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [org.hotswap.agent.plugin.hotswapper.HotswapperPlugin, org.hotswap.agent.plugin.jvm.AnonymousClassPatchPlugin, org.hotswap.agent.plugin.hibernate.HibernatePlugin, org.hotswap.agent.plugin.spring.SpringPlugin, org.hotswap.agent.plugin.jetty.JettyPlugin, org.hotswap.agent.plugin.tomcat.TomcatPlugin, org.hotswap.agent.plugin.zk.ZkPlugin, org.hotswap.agent.plugin.logback.LogbackPlugin] ... HOTSWAP AGENT: 9:49:38.700 INFO (org.hotswap.agent.plugin.spring.SpringPlugin) - Spring plugin initialized - Spring core version '3.2.3.RELEASE'
4.再定義の確認
変更されたリソースを保存するか、IDE のホットスワップ機能を使用して変更を再ロードします。
各アプリケーション フレームワーク (Spring、Hibernate、Logback など) には、クラスの再定義後に最新の状態を保つための特別なリロード メカニズムが必要です (たとえば、新しいエンティティ クラスが導入された後の Hibernate 構成のリロード)。ホットスワップ エージェントはプラグイン システムとして機能し、すべての主要なフレームワーク プラグインが事前に構成された状態で出荷されます。カスタム プラグインはアプリケーションの一部としても簡単に作成できます。
このプロジェクトは、サポートされているフレームワークとさまざまなバージョンが多数あるため、非常に複雑です。それを存続させるためにはコミュニティへの貢献が必須です。アプリケーション内にプラグインを作成するか、サンプル/統合テストを作成することから始めることができます。ドキュメントの改善は常に必要です:-)。助けていただきありがとうございます!
強化された Java ホットスワップ - メソッド本体の変更、メソッド、フィールドの追加/名前変更...サポートされていない唯一の操作は、スーパークラスの変更です。
デバッグモードでIDEから標準のJavaホットスワップを使用して、変更されたクラスをリロードできます。
または、autoHotswap プロパティ-XXaltjvm=dcevm -javaagent:PATH_TO_AGENThotswap-agent.jar=autoHotswap=true
を設定して、コンパイル後に変更されたクラスを再ロードします。この設定により、実稼働システムで再起動せずにリロードすることもできます。
自動構成 - 実行中の Java アプリケーションに認識されているすべてのローカル クラスとリソースが自動的に検出され、リロードが監視されます (JAR ファイル内ではなく、ローカル ファイル システム上のすべてのファイル)。
追加のクラスパス - 依存する JAR 内のランタイム クラスを変更する必要がありますか? extraClasspath プロパティを使用して、クラス ファイルを監視するクラスパスとして任意のディレクトリを追加します。
変更後にリソースを再ロードする - 通常、webapp ディレクトリのリソースはアプリケーション サーバーによって再ロードされます。しかし、src/main/resources などの他のリソースはどうなるのでしょうか? watchResources プロパティを使用して、リソースの変更を監視するディレクトリを追加します。
フレームワークのサポート - プラグイン システムを通じて、多くのフレームワークがサポートされています。新しいプラグインは簡単に追加できます。
高速 - プラグインが初期化されるまで、リソースを消費したり、アプリケーションの速度を低下させたりしません (詳細については、「実行時のオーバーヘッド」を参照)
問題や質問がある場合は、HotswapAgent フォーラムで質問してください。
このプロジェクトは JRebel に似ています。主な違いは次のとおりです。
HotswapAgent (DCEVM) は Java8、Java11、および Java17 をサポートします。
HotswapAgent では、基本的なプロジェクトのセットアップに追加の構成は必要ありません。
JRebel は現在、より成熟しており、より多くのプラグインが含まれています。
JRebel はオープンソースでも無料でもありません。
JRebel はリロード時にすべてのクラスのバイトコードを変更します。デバッグを修正するには特別な IDE プラグインが必要です。
HotswapAgentのextraClasspathはJRebel構成に似ています
HotswapAgent は watchResources 構成を追加します
HotswapAgentExamples GitHub プロジェクトを参照してください。サンプル アプリケーションの目的は次のとおりです。
複雑な自動統合テスト (リリース前にさまざまな構成を確認します。run run-tests.sh
スクリプトを参照)
プラグイン開発中(つまりコンテナ内)の「現実世界」のプラグインの使用状況を確認するため
一般的なアプリケーション設定に有効なソリューションを提供する
既存または新しいセットアップの問題をシミュレートするサンドボックス
自由にフォーク/分岐して、セットアップ用のアプリケーションを作成してください (機能的ですが、できるだけシンプルです)。一般的な設定はマスターにマージされます。
何も必要ありません:)本当に!すべての変更は透過的であり、パッチとエージェントをダウンロードし、アプリケーション/アプリケーション サーバーをセットアップするだけで済みます。標準の Java ホットスワップ動作を使用しているため、IDE は期待どおりに動作します。ただし、ダウンロードと構成を支援する IDE プラグインに取り組んでいます。
いくつかのプラグインはすでに利用可能です。
Intellij の [デバッグ] ボタンの横に、ホットスワップで実行、ホットスワップでデバッグという 2 つのアクションを追加します。
アクションをクリックすると、vm パラメータが設定されます。vm パラメータを手動で設定する必要はありません。
ソース コードとドキュメント: https://github.com/gejun123456/HotSwapHelper。
基本構成は、実行中のアプリケーション (クラスローダー) に認識されているクラスパスからクラスとリソースをリロードするように設定されています。別の構成が必要な場合は、 hotswap-agent.properties ファイルをクラスパス ルート (例: src/main/resources/hotswap-agent.properties
) に追加します。
使用可能なプロパティとデフォルト値の詳細なドキュメントは、エージェント プロパティ ファイルにあります。
コマンドラインオプションの完全な構文は次のとおりです。
-javaagent:[yourpath/]hotswap-agent.jar=[option1]=[value1],[option2]=[value2]
ホットスワップ エージェントは次のオプションを受け入れます。
autoHotswap=true - すべての .class ファイルの変更を監視し、(IDE デバッグ セッションからホットスワップを実行するのではなく) 実行中のアプリケーションでクラスを自動的にホットスワップします。
disablePlugin=[pluginName] - プラグインを無効にします。これにより、プラグインのロードが完全に禁止されることに注意してください (クラスローダーのプラグインのみを無効にする hotswap-agent.properties の disablePlugin オプションとは反対です)。無効にするすべてのプラグインに対してこのオプションを繰り返すことができます。
vm オプション -Dhotswapagent.disablePlugin=Spring,SpringBoot を追加してプラグインを無効にします。前のセクションのエージェント オプション disablePlugin と同じように機能します。
ホットスワップ エージェントは、リソースとフレームワーク構成 (Spring、Hibernate など) を再ロードする作業を行いますが、クラスを再ロードするための標準 Java ホットスワップ メカニズムに依存します。標準の Java ホットスワップではメソッド本体の変更しか許可されないため、実質的には使用できません。 DCEVM は、ホットスワップでのほぼすべての構造クラスの変更を可能にする JVM (ホットスポット) パッチです (階層の変更を除く)。ホットスワップ エージェントは標準 Java でも動作しますが、DCEVM を使用することをお勧めします (すべてのチュートリアルではターゲット JVM として DCEVM を使用します)。
ホットスワップ エージェントは、プラグイン マネージャー、プラグイン レジストリ、およびいくつかのエージェント サービス (クラス/リソースの変更を監視するためなど) を備えたプラグイン コンテナーです。これは、一般的なタスクとクラスロードの問題に役立ちます。 @Plugin アノテーションが付けられたクラスのクラスパスをスキャンし、エージェント サービスを挿入し、リロード フックを登録します。実行時のバイトコード変更は、javaasist ライブラリによって提供されます。
ホットスワップ エージェントによって管理されるプラグインは通常、特定のフレームワークに重点を置いています。たとえば、Spring プラグインは HA サービスを使用して次のことを行います。
ルート Spring クラスを変更して Spring コンテキストと登録されたスキャンパスを取得する
スキャンパス上のリソースの変更を監視する
スキャンパス パッケージ内のクラス ファイルのホットスワップを監視します。
変更後に Bean 定義をリロードする
...その他多くの
CXF-JAXRS (3.x) - リソースクラスの再定義後に JAXRS リソースを再定義し、Spring および CDI (Weld/OWB) と統合されている場合はインスタンスを再挿入します。
Deltaspike (1.x、2.x) - メッセージ、ViewConfig、リポジトリ、プロキシのリロード。 Deltaspike スコープの CDI Bean の再注入。
ELResolver (2.x-5.x) (JuelEL、Appache Commons EL、Oracle EL 3.0) - クラス変更時に ELResolver キャッシュをクリアします。 #{...} 式のホットスワップをサポートします。
FreeMarker - クラス定義の変更時に Apache Freemark Bean のクラスイントロスペクション キャッシュをクリアします。
Hibernate (3.x-6.x) - エンティティの作成/変更後に Hibernate 設定をリロードします。
iBatis - iBatis 設定のリロード。
IDEA - IDEA での IntelliJ IDEA 開発のサポート
Jackson - クラスが再定義されたときにジャクソンの内部キャッシュをクリアします。
Jersey1 - ルート リソースまたはプロバイダー クラスの定義または再定義後に Jersey1 コンテナーをリロードします。
Jersey2 - ルート リソースまたはプロバイダー クラスの定義または再定義後に Jersey2 コンテナをリロードします。
ログバック - ログバック構成のリロード。
Log4j2 - Log4j2 構成のリロード。
Mojarra (2.x) - アプリケーション リソース バンドルの変更のサポート (プロパティ ファイル)。 ViewScoped Bean の再注入/再ロードのサポート。
MyBatis (5.3) - マッパー ファイル変更後の設定のリロード
MyFaces (2.x-4.x) - アプリケーション リソース バンドルの変更 (プロパティ ファイル) のサポート。 ViewScoped Bean の再注入/再ロードのサポート。
OmniFaces - ViewScoped Bean の再注入/再ロードのサポート。
OpenWebBeans - (CDI) (1.x-4.x) - クラス定義/変更後に Bean クラス定義を再ロードします。 Bean は、プロパティ ファイルで定義された戦略に従って再ロードできます。
OsgiEquinox - Eclipse プラグインまたは Eclipse プラットフォーム開発のためのホットスワップ サポート。
RestEasy (2.x、3.x) - クラスの再定義をクリーンアップして登録します。
Spring (3.2.x+、4.x、5.x) - クラス定義/変更後に Spring 構成をリロードします。
Spring Boot (1.5.x+、2.0.x) - Spring Boot 構成ファイルをリアルタイムで動的にリロードします。
Vaadin (23.x、24.x) - ルート、テンプレート モデル、そして実際にはあらゆるものをその場で更新します。
WebObjects - クラス変更後にキー値コーディング、コンポーネント、アクション、および検証キャッシュをクリアします。
Weld (CDI) (2.x-5.x) - クラス定義/変更後に Bean クラス定義を再ロードします。 Bean は、プロパティ ファイルで定義された戦略に従って再ロードできます。
Wicket - プロパティファイルが変更された場合に Wicket キャッシュをクリアします
WildFlyELResolver - クラスの再定義後に BeanELResolver をクリアします。
ZK (5x-7x) - ZK フレームワーク (http://www.zkoss.org/)。ライブラリ プロパティのデフォルト値を変更してキャッシュを無効にし、ラベル キャッシュと Bean リゾルバ キャッシュを維持します。
JBossModules - JBoss のモジュール クラス ローダーに追加のクラスパスを追加します。 (ワイルドフライ)
Jetty - アプリのクラスローダーに追加のクラスパスを追加します。 WebAppContext.getExtraClasspath をサポートするすべてのバージョンがサポートされる必要があります。
Tomcat (7.x、8.x、9.x、10.x) は、extraClasspath と webApp プロパティを使用して Apache Tomcat を構成します。 GlassFish、Payara、Tomee7 もサポートしています。
Undertow - 追加のクラスパス、watchResources、および webappDir を undertow のリソース マネージャーに追加します。
Weblogic - アプリのクラスローダーに追加のクラスパスを追加します。
AnonymousClassPatch - 互換性のない変更を避けるために、匿名の内部クラス名を交換します。
ClassInit - クラス/列挙型の再定義後に新しい静的メンバー/列挙値を初期化し、静的値を存続させます。 (既知の DCEVM 制限の修正)
ホットスワッパー - クラス ファイルの変更を監視し、Java プラットフォーム デバッガー アーキテクチャ (JPDA) 経由でオンザフライでリロード (ホットスワップ) します。
プロキシ (com.sun.proxy、CGlib をサポート) - 変更されたインターフェイスまたはクラスを実装または拡張するプロキシ クラスを再定義します。
プラグイン プロジェクトのメイン README.md ファイルで各プラグインの詳細なドキュメントを見つけてください。
それは、使用するフレームワークの数と、どのキャッシュが無効になっているかによって異なります。 Jetty 上で実行される Spring + Hibernate に基づく大規模な実際のエンタープライズ アプリケーションの測定例。
Setup | Startup time -----------------------------|------------- Run (plain Java) | 23s Debug (plain Java) | 24s Debug (plain DCEVM) | 28s Agent - disabled all plugins | 31s Agent - all plugins | 35s
プラグインをアプリケーションの一部として直接作成できます。 @Plugin
アノテーション付きクラスを検出するには、 hotswap-agent.properties
構成内でpluginPackages=your.plugin.package
を設定します。コンパイルするにはエージェント JAR 依存関係も必要ですが、JAR をアプリケーションに追加しないように注意してください。 Javaagent としてのみロードする必要があります。 Maven の依存関係:
org.hotswapagent HotswapAgent ${project.version} provided
コメント化された単純なプラグインについては、「ExamplePlugin (TestApplication の一部)」を参照してください。エージェントの概念を理解するには、エージェントの Readme を読んでください。他の例については、既存のプラグインのソース コードを確認してください。
メインディレクトリでrun-tests.sh
スクリプトを起動します。現在、JAVA_HOME の場所のディレクトリを手動で設定する必要があります。リリース前に、少なくとも DCEVM を備えた Java 11 をチェックする必要があります。すべての自動テストは、単一のテストが失敗した場合にスクリプト全体が失敗するように設定されています。
リポジトリのルートを表すディレクトリに移動します。 DCEVM の名前がdcevm
の場合
mvn release:prepare mvn release:perform
ホットスワップ エージェント:
Jiri Bubnik - プロジェクト コーディネーター、初期実装
Alexandros Papadakis - Maven バージョニング、Weld、JSF、Hibernate3、RestEasy、WildFly プラグイン
Erki Ehtla - Spring プラグイン、プロキシ プラグイン
Vladimir Dvorak - ELResolver、OsgiEquinox、Weld、Owb、Deltaspike、Jvm、Jdk、JBossModules、ClassInit、JSF、Mybatis
Sergey Lysenko - Weld プラグイン
Samuel Pelletier - WebObjects プラグイン
Jan Tecl - ウェブデザイン
@liuzhengyang - ジャクソンプラグイン
Lukasz Warzecha - Log4j2 プラグイン
@muwaiwai - iBatis プラグイン
Thomas Heigl - Wicket プラグイン
AJ Bank - FreeMarker プラグイン
Sinan Yumak - Mojarra、MyFaces プラグイン
smallfour - Mybatis プラグイン
@cvictory - Spring プラグイン、Spring Boot プラグイン
@homejim - MyBatis プラグイン、MyBatisPlus プラグイン
DCEVM:
Thomas Würthinger - 初期実装。
Ivan Dubrov - 元プロジェクト コーディネーター、Java7+Java8 へのアップデート、パッチ、ビルド システム (Gradle)
Kerstin Breitender - 寄稿者。
クリストフ・ウィンバーガー - 寄稿者。
Vladimir Dvorak - java9、java11、jbr17、jbr21 移行、寄稿者
Jiri Bubnik - java9、java11 の移行