モジュール java.instrument
パッケージ java.lang.instrument

インタフェースClassFileTransformer


public interface ClassFileTransformer
クラス・ファイルのトランスフォーマ。 エージェントは、addTransformerメソッドを使用してこのインタフェースの実装を登録し、クラスのロード時にトランスフォーマのtransformメソッドが呼び出されるようにします。redefinedまたはretransformed 実装は、ここで定義されているtransformメソッドの1つをオーバーライドする必要があります。 トランスフォーマは、Java仮想マシンによってクラスが定義される前に呼び出されます。

Instrumentation.addTransformer(ClassFileTransformer,boolean)canRetransformパラメータに応じて2種類のトランスフォーマがあります。

  • trueとしてcanRetransformに追加された再変換可能トランスフォーマ
  • falseとしてcanRetransformに追加された、またはInstrumentation.addTransformer(ClassFileTransformer)に追加された、再変換不可能トランスフォーマ

トランスフォーマがaddTransformerで登録されると、トランスフォーマは、新しいクラス定義とクラス再定義のたびに呼び出されます。 再変換可能トランスフォーマは、クラスの再変換のたびにも呼び出されます。 新しいクラス定義の要求は、ClassLoader.defineClassまたはこのネイティブの同等のものを使って行われます。 クラス再定義の要求は、Instrumentation.redefineClassesまたはこのネイティブの同等のものを使って行われます。 クラス再変換の要求は、Instrumentation.retransformClassesまたはこのネイティブの同等のものを使って行われます。 トランスフォーマは、クラス・ファイル・バイトが確認または適用される前に、要求の処理中に呼び出されます。 複数のトランスフォーマが存在する場合、変換はtransform呼出しのチェーンによって構成されます。 つまり、transformの呼出しによって返されるバイト配列は、classfileBufferパラメータを介して、その次の呼出しの入力になります。

変換は次の順序で適用されます。

  • 再変換不可能トランスフォーマ
  • 再変換不可能ネイティブ・トランスフォーマ
  • 再変換可能トランスフォーマ
  • 再変換可能ネイティブ・トランスフォーマ

再変換では、再変換不可能トランスフォーマは呼び出されず、直前の変換結果が再利用されます。 それ以外の場合は、このメソッドが呼び出されます。 トランスフォーマのそれぞれの種類内では、登録された順序でトランスフォーマが呼び出されます。 ネイティブ・トランスフォーマはJava仮想マシン・ツール・インタフェースのClassFileLoadHookイベントで提供されます。

最初のトランスフォーマへの入力は、classfileBufferパラメータを介して渡され、次のようになります。

  • 新しいクラス定義の場合は、ClassLoader.defineClassに渡されるバイト
  • クラス再定義の場合は、definitions.getDefinitionClassFile()。ここで、definitionsInstrumentation.redefineClassesのパラメータ
  • クラス再変換の場合は、新しいクラス定義に渡されるバイト。再定義された場合は最新の再定義。いずれの場合も、再変換不可能トランスフォーマによって行われるすべての変換がそのまま自動的に再適用され、不変である。詳細については、Instrumentation.retransformClassesを参照

実装しているメソッドが変換不要と判定すると、メソッドはnullを返します。 変換が必要と判定すると、メソッドは新しいbyte[]配列を作成し、すべての必要な変換とともにclassfileBuffer入力をその配列の中にコピーし、新しい配列を返します。 classfileBuffer入力は変更されません。

再変換と再定義のケースでは、トランスフォーマは、再定義セマンティックスをサポートしなければいけません。初期定義中にトランスフォーマが変更したクラスがあとで再変換または再定義される場合、トランスフォーマは、2番目のクラスの出力クラス・ファイルで最初の出力クラス・ファイルが正当に再定義されていることを確認しなければいけません。

トランスフォーマがキャッチしない例外をスローする場合は、それ以降もトランスフォーマが呼び出され、ロードや再定義が試行されます。 このため、例外をスローすることはnullを返すことと同じになります。 非チェック例外がトランスフォーマ・コードで生成されるときに予期しない動作が起こらないようにするため、トランスフォーマはThrowableをキャッチすることができます。 classFileBufferが有効にフォーマットされたクラス・ファイルを表さないとトランスフォーマが判定した場合、トランスフォーマはIllegalClassFormatExceptionをスローする必要があります。これにはnullを返すのと同じ効果がありますが、形式の不備についてのログの作成やデバッグを容易にします。

「クラス・ファイル」という用語は、「Java Virtual Machine仕様」の3.1の項で定義されているように、ファイルに存在するかどうかに関係なく、クラス・ファイル形式の一連のバイトを意味します。

導入されたバージョン:
1.5
関連項目: