web-dev-qa-db-ja.com

ホットスワップメカニズムを介して実行時にメソッドを変更する

単純なJavaプログラムが1つのクラスのみで構成されているとします。

public class HelloWorld {

   private static void replacable(int i) {
      System.out.println("Today is a Nice day with a number " + i);
   }        

   public static void main(String[] args) throws Exception {
      for(int i = 0; i < 100000; ++i) {
      replacable(i);
      Thread.sleep(500);
   }
}

コンパイルして実行すると、出力は次のようになります。

今日は数字の0でいい日です

今日は素敵な一日です1

今日は2番のいい日です

今日は3番でいい日です

...

私の質問:実行時にreplacableメソッドを交換する何らかの方法が存在しますか(地平線上にありますか)? HelloWorldの新しいバージョンでreplacableの別のバージョンを作成し、それをコンパイルしてから、すでに実行中のJVMで古いバージョンをコンパイルするようなものでしょうか。

したがって、このように新しいバージョンを作成する場合:

private static void replacable(int i) {
   System.out.println("Today is an even nicer day with a number " + i);
}  

私がこれを行うことができる Erlangのホットコードスワッピング に似たものがあります:

  1. オリジナルプログラムを実行する
  2. 修正版を書く
  3. コマンドラインプログラムを使用して、実行中のJVMに接続し、既存のメソッドを置き換える

そのため、実行時に次のことが起こります。

今日は15000番のいい日です

今日は15001という数字のいい日です

今日はさらに良い日で、数字は15002です。

今日は15003という数字でさらに良い日です

...

上記のプログラムはスタンドアロンであり、標準のJava SE環境で実行され、クラスパスには他に何もないため、ほとんどHello worldスタイルのプログラムです。

注:バイトコード操作( cglib )などのテクノロジー、 aspectJjRebel[〜#〜] jmx [〜#〜] 、Java EEなどのメソッドのホットスワップが存在しますが、私が考えているものではありません。Erlangについて考えてください。

56
darioo

オープンソース HotSpot VM または商用 JRebel IDEプラグインを使用して、簡単に目標を達成できます(比較表を表示- ここ )。

38
Arun

クラスローダーを介してそれを行うことができます。たとえば、開発中にページを変更するとページをリロードするTomcatなどのサーブレットコンテナに慣れている場合。 Javaでの動的コードの作成に関する優れた説明 です。ロードについて説明するだけでなく、ソースをオンザフライでコンパイルします。使用したいコードをリロードする戦略に、カバーされている概念を適用できるはずです。

15
M. Jessup

多くのプロジェクトでこれを使用しました hotswap ant task ターゲットJavaアプリケーションは、適切なポートを開いてデバッグモードで起動する限り、Ant、Eclipse、コマンドプロンプト、またはその他の方法で起動できます。 Antを介してこれを行う方法。

変更が構造的でない限り、任意の数のクラスをホットスワップできます。メソッド本体は一般にホットスワップが簡単に変更されます。 ShellまたはEclipseを介してantスクリプトを実行することにより、コードをホットスワップできます。

職場では、クラスファイルのタイムスタンプを比較して、コードの変更を自動的にホットスワップするスクリプトを使用しています。これは、変更されたクラスをホットスワップするだけの簡単な例を示すプロジェクトページのサンプルに似ています。

追記:これは [〜#〜] jpda [〜#〜] を利用します。

9
Andy

少し古い記事ですが、うまくいけば誰かがこれを役に立つと思うでしょう:

比較的新しい Hotswap Agent が十分に文書化されており、機能が豊富であることがわかりました(そして何よりも オープンソース )。

3
aspiring_sarge

これは、JPDA(Java Platform Debugger Architecture)インターフェースを介して実行できます。 http://download.Oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap

Erlangの場合のように自動ではありません-JVMはクラスファイルへの変更についてクラスパスを監視せず、変更された場合はリロードして再リンクします。これは、明らかな理由によります(JavaはポーリングしたくないWebデプロイメント用に設計されました変更のためのhttp URL)。

2
Pete Kirkham

Strategyデザインパターンを使用すると、メソッドではなく操作するオブジェクトと、指定されたクラス名をStrategyオブジェクトのクラスとして使用するようにプログラムと通信するためのプロトコルを使用できます。

1
Raedwald

OSGiはどうですか?ホットスワッピングは、仕様に「組み込まれた」ものです。これも、可能な解決策の1つだと思います。

1
javamonkey79