public interface ClassFileTransformer
クラスファイルという用語は、『Java™ 仮想マシン仕様』のセクション 3.1 の定義に従って使用され、バイトシーケンスがファイルに存在するかどうかにかかわらず、クラスファイル形式のバイトシーケンスを意味します。
修飾子と型 | メソッドと説明 |
---|---|
byte[] |
transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer)
このメソッドの実装は、提供されたクラスファイルを変換して、新しい置換クラスファイルを返すことができます。
|
byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException
Instrumentation.addTransformer(ClassFileTransformer,boolean)
の canRetransform
パラメータに応じて 2 種類のトランスフォーマがあります。
canRetransform
に追加された再変換可能トランスフォーマ
canRetransform
に追加された、または Instrumentation.addTransformer(ClassFileTransformer)
に追加された、再変換不可能トランスフォーマ
トランスフォーマが addTransformer
で登録されると、トランスフォーマは、新しいクラス定義とクラス再定義のたびに呼び出されます。再変換可能トランスフォーマは、クラスの再変換のたびにも呼び出されます。新しいクラス定義の要求は、ClassLoader.defineClass
またはこのネイティブの同等のものを使って行われます。クラス再定義の要求は、Instrumentation.redefineClasses
またはこのネイティブの同等のものを使って行われます。クラス再変換の要求は、Instrumentation.retransformClasses
またはこのネイティブの同等のものを使って行われます。トランスフォーマは、クラスファイルバイトが確認または適用される前に、要求の処理中に呼び出されます。複数のトランスフォーマが存在する場合、変換は transform
呼び出しのチェーンによって構成されます。つまり、transform
の呼び出しによって返されるバイト配列は、classfileBuffer
パラメータを介して、その次の呼び出しの入力になります。
変換は次の順序で適用されます。
再変換では、再変換不可能トランスフォーマは呼び出されず、直前の変換結果が再利用されます。それ以外の場合は、このメソッドが呼び出されます。トランスフォーマのそれぞれの種類内では、登録された順序でトランスフォーマが呼び出されます。ネイティブトランスフォーマは Java 仮想マシンツールインタフェースの ClassFileLoadHook
イベントで提供されます。
最初のトランスフォーマへの入力は、classfileBuffer
パラメータを介して渡され、次のようになります。
ClassLoader.defineClass
に渡されるバイト
definitions.getDefinitionClassFile()
。ここで、definitions
は Instrumentation.redefineClasses
のパラメータ
Instrumentation.retransformClasses
を参照
実装しているメソッドが変換不要と判定すると、メソッドは null
を返します。変換が必要と判定すると、メソッドは新しい byte[]
配列を作成し、すべての必要な変換とともに classfileBuffer
入力をその配列の中にコピーし、新しい配列を返します。classfileBuffer
入力は変更されません。
再変換と再定義のケースでは、トランスフォーマは、再定義セマンティクスをサポートしなければいけません。初期定義中にトランスフォーマが変更したクラスがあとで再変換または再定義される場合、トランスフォーマは、2 番目のクラスの出力クラスファイルで最初の出力クラスファイルが正当に再定義されていることを確認しなければいけません。
トランスフォーマがキャッチしない例外をスローする場合は、それ以降もトランスフォーマが呼び出され、ロードや再定義が試行されます。このため、例外をスローすることは null
を返すことと同じになります。非チェック例外がトランスフォーマコードで生成されるときに予期しない動作が起こらないようにするため、トランスフォーマは Throwable
をキャッチすることができます。classFileBuffer
が有効にフォーマットされたクラスファイルを表さないとトランスフォーマが判定した場合、トランスフォーマは IllegalClassFormatException
をスローする必要があります。これには null を返すのと同じ効果がありますが、形式の不備についてのログの作成やデバッグを容易にします。
loader
- 変換されるクラスを定義しているローダー。ブートストラップローダーの場合は null
className
- 『Java 仮想マシン仕様』で定義されている完全指定クラスの内部形式のクラス名とインタフェース名。たとえば、"java/util/List"
です。classBeingRedefined
- 再定義または再変換によってトリガーされた場合は、再定義または再変換されているクラス。これがクラスロードの場合は、null
protectionDomain
- 定義または再定義されているクラスの保護領域classfileBuffer
- クラスファイル形式の入力バイトバッファー (変更されてはならない)null
。IllegalClassFormatException
- 入力が整形式のクラスファイルを表さない場合Instrumentation.redefineClasses(java.lang.instrument.ClassDefinition...)
バグまたは機能を送信
詳細な API リファレンスおよび開発者ドキュメントについては、Java SE のドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.