2011-01-28 1 views

答えて

43

JRebelはクラスの書き換え(ASMとJavassistの両方)とJVMの統合を使って個々のクラスをバージョン化しています。さらに、アプリケーションサーバーと統合して、クラス/リソースおよびWebサーバーのルックアップをワークスペースにリダイレクトします。また、ほとんどのアプリサーバーやフレームワークと統合して、構成(メタデータまたはファイル)の変更を伝播します。それはそれの不足です。その長さには、開発とサポートのために10人の世界的なエンジニアが必要であり、私たちの商業秘密です:

+2

@Jevgeni Kabanov:JRebelは、最終的なクラスのリロードを処理しますか? – Dexter

+1

@Dexter –

4

これは私がJRebel worksのSimon、ZTテクニカルエバンジェリストによってどのように読み込まれたかに最も近い推論です。


Jrebel楽器間接のレイヤーを作成するためのアプリケーションとJVMクラス:ここに内容を貼り付ける

。アプリケーション・クラスがロードされると、図2に示すように、すべてのメソッド本体は、実行時リダイレクション・サービスを使用してリダイレクトされます。このサービスは、リロードされる各バージョンに対して作成された匿名内部クラスを使用してクラスおよびメソッドのバージョンを管理およびロードします。例を見てみましょう。

public class C extends X { 
int y = 5; 
int method1(int x) { 
    return x + y; 
} 
void method2(String s) { 
    System.out.println(s); 
} 
} 

クラスCを最初に読み込むと、JRebelがクラスをインストルメントします。このクラスのシグネチャは同じですが、メソッド本体がリダイレクトされています。私たちは呼ばれている方法で、私たちのクラス名、私たちのメソッド名とタイプのため、呼び出し元のオブジェクトにパラメータを渡す、リダイレクト呼び出しに

public class C extends X { 
int y = 5; 
int method1(int x) { 
    Object[] o = new Object[1]; 
    o[0] = x; 
    return Runtime.redirect(this, o, "C", "method1", "(I)I"); 
} 
void method2(String s) { 
    Object[] o = new Object[1]; 
    o[0] = s; 
    return Runtime.redirect(this, o, "C", "method2", "(Ljava/lang/String;)V"); 
} 
} 

:ロードされたクラスは、次のようになりますパラメータと戻り値。 JRebelはまた、特定のバージョンで実装を持つクラスをロードし、最初はバージョン0でのは、それがどのようなものか見てみましょう:

public abstract class C0 { 
public static int method1(C c, int x) { 
    int tmp1 = Runtime.getFieldValue(c, "C", "y", "I"); 
    return x + tmp1; 
} 
public static void method2(C c, String s) { 
    PrintStream tmp1 = 
    Runtime.getFieldValue(
     null, "java/lang/System", "out", "Ljava/io/PrintStream;"); 
    Object[] o = new Object[1]; 
    o[0] = s; 
    Runtime.redirect(tmp1, o, "java/io/PrintStream;", "println","(Ljava/lang/String;)V"); 
} 
} 

さんは今、ユーザーが(新しいメソッドzを追加)し、呼び出すことによってそのクラスCを変更するとしましょうそれは方法1からです。クラスCは次のようになります。

public class C { 
int y = 5; 
int z() { 
    return 10; 
} 
int method1(int x) { 
    return x + y + z(); 
} 
... 
} 

次回ランタイムはこのクラスを使用して、JRebelはコンパイルおよびファイルシステム上にされた新しいバージョンがある検出し、それはC1、新バージョンをロードします。このバージョンには、メソッドzとメソッド1の更新された実装が追加されています。

public class C1 { 
public static int z(C c) { 
    return 10; 
} 
public static int method1(C c, int x) { 
    int tmp1 = Runtime.getFieldValue(c, "C", "y", "I"); 
    int tmp2 = Runtime.redirect(c, null, "C", "z", "(V)I"); 
    return x + tmp1 + tmp2; 
} 
... 
} 

Runtime.redirectコールは常にので、新しいC()。法1(10)は、その後、コードの変更前の15と25を返す呼び出し、クラスCの最新バージョンにルーティングされます。この実装は多くの詳細と最適化を欠場しますが、あなたはそのアイデアを得ます。

出典:http://zeroturnaround.com/rebellabs/why-hotswap-wasnt-good-enough-in-2001-and-still-isnt-today/

関連する問題