public interface Instrumentation
Instrumentation
インタフェースのインスタンスを取得する方法は2つあります。
エージェント・クラスを指定する方法でJVMを起動した場合。 この場合、
Instrumentation
インスタンスは、そのエージェント・クラスのpremain
メソッドに渡されます。JVMの開始後にエージェントを開始するメカニズムがJVMに用意されている場合。 この場合、
Instrumentation
インスタンスは、そのエージェント・コードのagentmain
メソッドに渡されます。
これらのメカニズムは、パッケージの仕様で説明します。
エージェントがInstrumentation
インスタンスを取得すると、インスタンス上のメソッドをいつでも呼び出すことができます。
- APIのノート:
- このインタフェースは、java.instrumentモジュール外で実装することを意図していません。
- 導入されたバージョン:
- 1.5
-
メソッドのサマリー
修飾子と型 メソッド 説明 void
addTransformer(ClassFileTransformer transformer)
提供されたトランスフォーマを登録します。void
addTransformer(ClassFileTransformer transformer, boolean canRetransform)
提供されたトランスフォーマを登録します。void
appendToBootstrapClassLoaderSearch(JarFile jarfile)
ブートストラップ・クラス・ローダーで定義されるインストゥルメンテーション・クラスでJARファイルを指定します。void
appendToSystemClassLoaderSearch(JarFile jarfile)
システム・クラス・ローダーで定義されるインストゥルメンテーション・クラスでJARファイルを指定します。Class[]
getAllLoadedClasses()
JVMにより現在ロードされているすべてのクラスの配列を返します。Class[]
getInitiatedClasses(ClassLoader loader)
loader
がClassLoader::loadClass
、Class::forName
およびバイトコード・リンケージを介して名前で検索できるすべてのクラスの配列を返します。long
getObjectSize(Object objectToSize)
指定されたオブジェクトにより消費される記憶領域の容量の実装固有の近似値を返します。boolean
isModifiableClass(Class<?> theClass)
retransformationまたはredefinitionによってクラスが変更可能かどうかをテストします。boolean
isModifiableModule(Module module)
redefineModule
でモジュールを変更できるかどうかをテストします。boolean
isNativeMethodPrefixSupported()
現在のJVM構成でネイティブ・メソッドの接頭辞の設定がサポートされるかどうかを返します。boolean
isRedefineClassesSupported()
現在のJVM構成がクラスの再定義をサポートしているかどうかを返します。boolean
isRetransformClassesSupported()
現在のJVM構成がクラスの再変換をサポートしているかどうかを返します。void
redefineClasses(ClassDefinition... definitions)
提供されたクラス・ファイルを使って提供されたクラスのセットを再定義します。void
redefineModule(Module module, Set<Module> extraReads, Map<String,Set<Module>> extraExports, Map<String,Set<Module>> extraOpens, Set<Class<?>> extraUses, Map<Class<?>,List<Class<?>>> extraProvides)
モジュールを再定義して、読み込んだモジュールのセット、エクスポートまたは開くパッケージのセット、または使用または提供するサービスを拡張します。boolean
removeTransformer(ClassFileTransformer transformer)
提供されたトランスフォーマの登録を解除します。void
retransformClasses(Class<?>... classes)
指定されたクラス・セットを再変換します。void
setNativeMethodPrefix(ClassFileTransformer transformer, String prefix)
このメソッドは、名前に接頭辞を適用して再試行できるようにして、ネイティブ・メソッド解決のエラー処理を変更します。
-
メソッドの詳細
-
addTransformer
void addTransformer(ClassFileTransformer transformer, boolean canRetransform)提供されたトランスフォーマを登録します。 これにより、登録されたトランスフォーマが依存するクラスの定義を除き、将来のすべてのクラス定義はトランスフォーマにより確認されます。 トランスフォーマは、クラスがロードされたとき、それらが再定義されたとき、およびcanRetransform
がtrueの場合にクラスが再変換されたときに呼び出されます。ClassFileTransformer
は変換呼び出しの順序を定義します。 トランスフォーマが実行中に例外をスローすると、JVMは登録されているその他のトランスフォーマを順に呼び出します。 同じトランスフォーマを複数回追加することはできますが、そうするべきではありません。これを避けるには、トランスフォーマ・クラスの新しいインスタンスを作成してください。このメソッドはインストゥルメンテーションで使用するためのものです(クラスの仕様を参照)。
- パラメータ:
transformer
- 登録するトランスフォーマcanRetransform
- このトランスフォーマの変換を再変換できるかどうか- 例外:
NullPointerException
-null
トランスフォーマを渡した場合UnsupportedOperationException
-canRetransform
がtrueであり、JVMの現在の設定が再変換(isRetransformClassesSupported()
がfalse)を許可しない場合- 導入されたバージョン:
- 1.6
-
addTransformer
void addTransformer(ClassFileTransformer transformer)提供されたトランスフォーマを登録します。addTransformer(transformer, false)
と同じ。- パラメータ:
transformer
- 登録するトランスフォーマ- 例外:
NullPointerException
-null
トランスフォーマを渡した場合- 関連項目:
addTransformer(ClassFileTransformer,boolean)
-
removeTransformer
boolean removeTransformer(ClassFileTransformer transformer)提供されたトランスフォーマの登録を解除します。 登録解除されたトランスフォーマは、将来クラス定義を確認できなくなります。 直前に追加された一致するトランスフォーマのインスタンスを削除します。 クラス・ローディングのマルチ・スレッド的性質により、削除されたあとでもトランスフォーマを呼び出すことができます。 このような状況を考慮して、慎重にトランスフォーマを記述する必要があります。- パラメータ:
transformer
- 登録を解除するトランスフォーマ- 戻り値:
- トランスフォーマが見つかり、削除された場合はtrue。トランスフォーマが見つからなかった場合はfalse
- 例外:
NullPointerException
-null
トランスフォーマを渡した場合
-
isRetransformClassesSupported
boolean isRetransformClassesSupported()現在のJVM構成がクラスの再変換をサポートしているかどうかを返します。 すでにロードされているクラスを再変換する機能は、JVMのオプションの機能です。 再変換がサポートされるのは、エージェントJARファイルでCan-Retransform-Classes
マニフェスト属性がtrue
に設定されていて(package specification参照)、かつJVMがこの機能をサポートしている場合に限られます。 単一のJVMの1つのインスタンス生成の間に、このメソッドに複数の呼出しを行うと、常に同じ答えが返されます。- 戻り値:
- 現在のJVM構成がクラスの再変換をサポートする場合はtrue、サポートしない場合はfalse
- 導入されたバージョン:
- 1.6
- 関連項目:
retransformClasses(java.lang.Class<?>...)
-
retransformClasses
void retransformClasses(Class<?>... classes) throws UnmodifiableClassException指定されたクラス・セットを再変換します。この機能は、すでにロード済みのクラスのインストゥルメンテーションを容易にします。 クラスがはじめてロードされる時や再定義される時に、その初期クラス・ファイル・バイトを
ClassFileTransformer
経由で変換することができます。 この関数は、以前に変換が行われたかどうかには関係なく、変換処理を再実行します。 この再変換はこれらのステップで行われます。- 初期クラス・ファイル・バイトから処理が開始されます。
canRetransform
がfalseで追加された各トランスフォーマに対して、最後のクラスのロードまたは再定義時にtransform
によって返されたバイトが変換の出力として再利用されます。これは以前の変換を変更せずにそのまま適用することと同等であることに注意してください。transform
メソッドが呼び出されない点が異なります。canRetransform
がtrueで追加されたトランスフォーマごとに、トランスフォーマ内でtransform
メソッドが呼び出される- 変換されたクラス・ファイル・バイトがクラスの新しい定義としてインストールされます。
変換の順序は
ClassFileTransformer
で説明されています。 再変換不可能トランスフォーマの自動再適用でも、同じ順序が使用されます。初期クラス・ファイル・バイトは、
ClassLoader.defineClass
またはredefineClasses
に渡されるバイト(変換が適用される前)を表しますが、厳密にそれらに一致しないことがあります。 定数プールは同じレイアウトまたは内容であるとは限りません。 定数プールのエントリ数が異なる可能性があります。 定数プールのエントリの順序が異なることがあります。ただし、メソッドのバイト・コードで定数プールのインデックスは対応します。 一部の属性が存在しない可能性があります。 順序が重要でない場合(メソッドの順序など)、順序が維持されない場合があります。このメソッドは、同時に1つ以上のクラスに対して相互依存の関係にある変更(クラスAの再変換はクラスBの再変換を必要とするなど)を可能にするためにセット上で動作します。
再変換されたメソッドがアクティブなスタック・フレームを持つ場合、アクティブなスタック・フレームは元のメソッドのバイト・コードを引き続き実行します。 再変換されたメソッドは新しい呼出しで使用されます。
このメソッドは、慣行のJVMセマンティックスの下で発生する初期化を除き、初期化を発生させません。 つまり、クラスの再定義では、クラスの初期化子は実行されません。 static変数の値は呼出し前の値のままに維持されます。
再変換されたクラスのインスタンスは影響を受けません。
サポートされているクラス・ファイルの変更は、JVM TI RetransformClassesで説明されています。 クラス・バイト・ファイルがチェック、検証、およびインストールされるのは、変換の適用後になります。得られるバイトがエラーになると、このメソッドは例外をスローします。
このメソッドが例外をスローした場合、クラスの再変換は行われません。
このメソッドはインストゥルメンテーションで使用するためのものです(クラスの仕様を参照)。
- パラメータ:
classes
- 再変換するクラスの配列。長さゼロの配列は使用できるが、使用した場合、このメソッドは何も実行しない- 例外:
UnmodifiableClassException
- 指定されたクラスを変更できない場合(isModifiableClass(java.lang.Class<?>)
からfalse
が返される)UnsupportedOperationException
- JVMの現在の設定が再変換(isRetransformClassesSupported()
がfalse)を許可しないか、再変換でサポートされない変更を加えようとした場合ClassFormatError
- データが有効なクラスを含まなかった場合NoClassDefFoundError
- クラス・ファイルの名前がクラスの名前と等しくない場合UnsupportedClassVersionError
- クラス・ファイル・バージョン番号がサポートされていない場合ClassCircularityError
- 新しいクラスが循環を含む場合LinkageError
- リンケージ・エラーが発生した場合NullPointerException
- 提供されたクラス配列またはそのコンポーネントのいずれかがnull
の場合。- 導入されたバージョン:
- 1.6
- 関連項目:
isRetransformClassesSupported()
、addTransformer(java.lang.instrument.ClassFileTransformer, boolean)
、ClassFileTransformer
-
isRedefineClassesSupported
boolean isRedefineClassesSupported()現在のJVM構成がクラスの再定義をサポートしているかどうかを返します。 すでにロードされているクラスを再定義する機能は、JVMのオプションの機能です。 再定義がサポートされるのは、エージェントJARファイルでCan-Redefine-Classes
マニフェスト属性がtrue
に設定されていて(package specification参照)、かつJVMがこの機能をサポートしている場合に限られます。 単一のJVMの1つのインスタンス生成の間に、このメソッドに複数の呼出しを行うと、常に同じ答えが返されます。- 戻り値:
- 現在のJVM構成がクラスの再定義をサポートする場合はtrue、サポートしない場合はfalse
- 関連項目:
redefineClasses(java.lang.instrument.ClassDefinition...)
-
redefineClasses
void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException提供されたクラス・ファイルを使って提供されたクラスのセットを再定義します。このメソッドを使用して、既存のクラス・ファイル・バイトへの参照のないクラスの定義を置き換えます。逐次デバッグを行うためにソースから再コンパイルするときに置換えが行われます。 既存のクラス・ファイル・バイトが変換されるときは(バイト・コード・インストゥルメンテーション内など)、
retransformClasses
を使用してください。このメソッドは、同時に1つ以上のクラスに対して相互依存の関係にある変更(クラスAの再定義はクラスBの再定義を必要とするなど)を可能にするためにセット上で動作します。
再定義されたメソッドがアクティブなスタック・フレームを持つ場合、アクティブなスタック・フレームは元のメソッドのバイト・コードを引き続き実行します。 再定義されたメソッドは新しい呼出しで使用されます。
このメソッドは、慣行のJVMセマンティックスの下で発生する初期化を除き、初期化を発生させません。 つまり、クラスの再定義では、クラスの初期化子は実行されません。 static変数の値は呼出し前の値のままに維持されます。
再定義されたクラスのインスタンスは影響を受けません。
サポートされているクラス・ファイルの変更は、JVM TI RedefineClassesで説明されています。 クラス・バイト・ファイルがチェック、検証、およびインストールされるのは、変換の適用後になります。得られるバイトがエラーになると、このメソッドは例外をスローします。
このメソッドが例外をスローした場合、クラスの再定義は行われません。
このメソッドはインストゥルメンテーションで使用するためのものです(クラスの仕様を参照)。
- パラメータ:
definitions
- 対応する定義を使って再定義するクラスの配列。長さゼロの配列は使用できるが、使用した場合、このメソッドは何も実行しない- 例外:
UnmodifiableClassException
- 指定されたクラスを変更できない場合(isModifiableClass(java.lang.Class<?>)
からfalse
が返される)UnsupportedOperationException
- JVMの現在の設定が再定義(isRedefineClassesSupported()
がfalse)を許可しないか、再定義でサポートされない変更を加えようとした場合ClassFormatError
- データが有効なクラスを含まなかった場合NoClassDefFoundError
- クラス・ファイルの名前がクラスの名前と等しくない場合UnsupportedClassVersionError
- クラス・ファイル・バージョン番号がサポートされていない場合ClassCircularityError
- 新しいクラスが循環を含む場合LinkageError
- リンケージ・エラーが発生した場合NullPointerException
- 提供された定義配列またはそのコンポーネントのいずれかがnull
の場合ClassNotFoundException
- スローすることはできない(互換性を維持するためにのみ存在する)- 関連項目:
isRedefineClassesSupported()
、addTransformer(java.lang.instrument.ClassFileTransformer, boolean)
、ClassFileTransformer
-
isModifiableClass
boolean isModifiableClass(Class<?> theClass)retransformationまたはredefinitionによってクラスが変更可能かどうかをテストします。 クラスが変更可能な場合、このメソッドはtrue
を返します。 クラスが変更不可能な場合、このメソッドはfalse
を返します。再変換されるクラスでは、
isRetransformClassesSupported()
もtrueである必要があります。 ただし、isRetransformClassesSupported()
の値は、この関数が返す値には影響しません。 再定義されるクラスでは、isRedefineClassesSupported()
もtrueである必要があります。 ただし、isRedefineClassesSupported()
の値は、この関数が返す値には影響しません。プリミティブ・クラス(
java.lang.Integer.TYPE
など)と配列クラスが変更可能になることはありません。- パラメータ:
theClass
- 変更可能かどうかをチェックするクラス- 戻り値:
- 引数クラスが変更可能かどうか
- 例外:
NullPointerException
- 指定されたクラスがnull
の場合。- 導入されたバージョン:
- 1.6
- 関連項目:
retransformClasses(java.lang.Class<?>...)
,isRetransformClassesSupported()
,redefineClasses(java.lang.instrument.ClassDefinition...)
,isRedefineClassesSupported()
-
getAllLoadedClasses
Class[] getAllLoadedClasses()JVMにより現在ロードされているすべてのクラスの配列を返します。 返される配列には、「非表示のクラスまたはインタフェース」を含むすべてのクラスとインタフェース、およびすべての型の配列クラスが含まれます。- 戻り値:
- JVMによりロードされたすべてのクラスを含む配列。クラスがない場合は長さゼロの配列
-
getInitiatedClasses
Class[] getInitiatedClasses(ClassLoader loader)loader
がClassLoader::loadClass
、Class::forName
およびバイトコード・リンケージを介して名前で検索できるすべてのクラスの配列を返します。 つまり、loader
が開始ローダーとして記録されているすべてのクラスです。 指定されたloader
がnull
の場合、ブートストラップ・クラス・ローダーが名前で検索できるクラスが返されます。返される配列には、「要素型」が「非表示のクラスまたはインタフェース」である「非表示のクラスまたはインタフェース」または配列クラスは含まれません。これらは、どのクラス・ローダーでも検出できないためです。
- パラメータ:
loader
- 起動したクラス・リストが返されるローダー- 戻り値:
loader
が名前で検索できるすべてのクラスを含む配列。存在しない場合は長さゼロ
-
getObjectSize
long getObjectSize(Object objectToSize)指定されたオブジェクトにより消費される記憶領域の容量の実装固有の近似値を返します。 結果には、オブジェクトのオーバーヘッドの一部またはすべてが含まれる可能性があります。したがって、実装内での比較には役立ちますが、実装間での比較には役立ちません。 この近似値は、JVMの単一呼出しの間に変わる可能性があります。- パラメータ:
objectToSize
- サイズを評価するオブジェクト- 戻り値:
- 指定されたオブジェクトにより消費される記憶領域の容量の実装固有の近似値
- 例外:
NullPointerException
- 提供されたオブジェクトがnull
の場合。
-
appendToBootstrapClassLoaderSearch
void appendToBootstrapClassLoaderSearch(JarFile jarfile)ブートストラップ・クラス・ローダーで定義されるインストゥルメンテーション・クラスでJARファイルを指定します。「ブートストラップ・クラス・ローダー」と呼ばれる仮想マシンの組込みクラス・ローダーがクラスの検索に失敗すると、
JAR file
内のエントリも検索されます。このメソッドを複数回使用して、このメソッドが呼び出される順序で検索される複数のJARファイルを追加できます。
インストゥルメンテーションをするために、エージェントではJARファイルにブートストラップ・クラス・ローダーで定義される以外のクラスまたはリソースが含まれないことを確認してください。 この警告の監視に失敗すると、診断するのが困難な予期しない動作になることがあります。 たとえばローダーLがあり、委譲のためのLの親がブートストラップ・クラス・ローダーであるとします。 また、クラスCがLで定義され、クラスCのメソッドがpublicでないアクセス用クラスC$1を参照するとします。 JARファイルにクラスC$1が含まれる場合、ブートストラップ・クラス・ローダーへの委譲により、C$1がブートストラップ・クラス・ローダーによって定義されます。 この例では
IllegalAccessError
がスローされてアプリケーションが失敗します。 このような問題を避ける1つの方法として、インストゥルメンテーション・クラスに一意のパッケージ名を使用します。「Java Virtual Machine仕様」は、Java仮想マシンが以前に解決に失敗したシンボリック参照を解決しようとする後続の試行が、最初の解決試行の結果としてスローされたのと同じエラーで常に失敗することを指定します。 したがって、Java仮想マシンが参照を解決できなかったクラスに対応するエントリがJARファイルに含まれる場合、その参照を解決しようとしても最初のエラーと同じエラーで失敗します。
- パラメータ:
jarfile
- ブートストラップ・クラス・ローダーがクラスの検索に失敗したときに検索されるJARファイル。- 例外:
NullPointerException
-jarfile
がnull
の場合。- 導入されたバージョン:
- 1.6
- 関連項目:
appendToSystemClassLoaderSearch(java.util.jar.JarFile)
,ClassLoader
,JarFile
-
appendToSystemClassLoaderSearch
void appendToSystemClassLoaderSearch(JarFile jarfile)システム・クラス・ローダーで定義されるインストゥルメンテーション・クラスでJARファイルを指定します。 委譲用のシステム・クラス・ローダー(getSystemClassLoader()
を参照)がクラスの検索に失敗したときに、JarFile
内のエントリも検索されます。このメソッドを複数回使用して、このメソッドが呼び出される順序で検索される複数のJARファイルを追加できます。
インストゥルメンテーションするために、エージェントはJARファイルにシステム・クラス・ローダーで定義される以外のクラスまたはリソースが含まれないことを確認する必要があります。 この警告の監視に失敗すると、診断するのが困難な予期しない動作になることがあります(
appendToBootstrapClassLoaderSearch
を参照)。システム・クラス・ローダーに
appendToClassPathForInstrumentation
メソッドが実装されている場合は、検索されるJARファイルの追加がサポートされます。このメソッドはjava.lang.String
型のパラメータ1つを取ります。 このメソッドは、public
アクセスを備えていなくてもかまいません。 JARファイルの名前は、jarfile
でgetName()
メソッドを呼び出すことで取得され、これはappendToClassPathForInstrumentation
メソッドへのパラメータとして提供されます。「Java Virtual Machine仕様」は、Java仮想マシンが以前に解決に失敗したシンボリック参照を解決しようとする後続の試行が、最初の解決試行の結果としてスローされたのと同じエラーで常に失敗することを指定します。 したがって、Java仮想マシンが参照を解決できなかったクラスに対応するエントリがJARファイルに含まれる場合、その参照を解決しようとしても最初のエラーと同じエラーで失敗します。
このメソッドは
java.class.path
system property
の値を変更しません。- パラメータ:
jarfile
- システム・クラス・ローダーがクラスの検索に失敗したときに検索されるJARファイル。- 例外:
UnsupportedOperationException
- システム・クラス・ローダーが検索されるJARファイルの追加をサポートしていない場合。NullPointerException
-jarfile
がnull
の場合。- 導入されたバージョン:
- 1.6
- 関連項目:
appendToBootstrapClassLoaderSearch(java.util.jar.JarFile)
,ClassLoader.getSystemClassLoader()
,JarFile
-
isNativeMethodPrefixSupported
boolean isNativeMethodPrefixSupported()現在のJVM構成でネイティブ・メソッドの接頭辞の設定がサポートされるかどうかを返します。 ネイティブ・メソッドの接頭辞を設定する機能は、JVMのオプション機能です。 ネイティブ・メソッドの接頭辞の設定がサポートされるのは、エージェントJARファイルでCan-Set-Native-Method-Prefix
マニフェスト属性がtrue
に設定されていて(package specification参照)、かつJVMがこの機能をサポートしている場合に限られます。 単一のJVMの1つのインスタンス生成の間に、このメソッドに複数の呼出しを行うと、常に同じ答えが返されます。- 戻り値:
- 現在のJVM設定がネイティブ・メソッドの接頭辞の設定をサポートする場合はtrue、サポートしない場合はfalse
- 導入されたバージョン:
- 1.6
- 関連項目:
setNativeMethodPrefix(java.lang.instrument.ClassFileTransformer, java.lang.String)
-
setNativeMethodPrefix
void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix)このメソッドは、名前に接頭辞を適用して再試行できるようにして、ネイティブ・メソッド解決のエラー処理を変更します。ClassFileTransformer
に使用すると、ネイティブ・メソッドをインストゥルメンテーションできます。ネイティブ・メソッドはバイト・コードを持たないので、直接計測できません。したがって、計測可能なネイティブでないメソッドでネイティブ・メソッドをラップする必要があります。 たとえば次を考えます。
native boolean foo(int x);
クラスの初期定義時にClassFileTransformerを使用してクラス・ファイルを変換すると次のようになります。
boolean foo(int x) { ... record entry to foo ... return wrapped_foo(x); } native boolean wrapped_foo(int x);
ここで、
foo
は実際のネイティブ・メソッドのラッパーで、接頭辞「wrapped_」が付加されています。 ただし、「wrapped_」は既存のメソッドの名前の一部として使用されている可能性があるため、接頭辞としてはよい選択肢ではありません。「$$$MyAgentWrapped$$$_」のような接頭辞の方が適切ですが、そうするとこの例が読みにくくなってしまいます。ラッパーによってネイティブ・メソッド呼出しのデータ収集が可能になりますが、次に問題となるのは、ラップされたメソッドとネイティブ実装との関連付けです。 つまり、メソッド
wrapped_foo
を次のようなネイティブ実装foo
に解決する必要があります。Java_somePackage_someClass_foo(JNIEnv* env, jint x)
この関数を使えば、接頭辞を指定し、適切な解決が行われるようにできます。 具体的には、標準の解決が失敗した場合に、接頭辞を考慮して再び解決が試みられます。 解決方法は2つあります。JNI関数
RegisterNatives
による明示的な解決と、通常の自動解決です。RegisterNatives
を使用する場合、JVMでは次の関連付けを行おうとします。method(foo) -> nativeImplementation(foo)
これに失敗すると、指定された接頭辞をメソッド名の先頭に追加して解決が再試行され、次のような正しい解決が得られます。
method(wrapped_foo) -> nativeImplementation(foo)
自動解決では、JVMは次の関連付けを行おうとします。
method(wrapped_foo) -> nativeImplementation(wrapped_foo)
これに失敗すると、指定された接頭辞を実装名から削除して解決が再試行され、次の正しい解決が得られます。
method(wrapped_foo) -> nativeImplementation(foo)
接頭辞が使用されるのは標準の解決が失敗した場合だけなので、ネイティブ・メソッドのラップは選択的に行えます。
各
ClassFileTransformer
では、独自のバイト・コード変換を行うことができるため、複数レイヤーのラッパーを適用できます。 そのため、各トランスフォーマには専用の接頭辞が必要です。 変換は順番に適用されるため、接頭辞を適用する場合、接頭辞は変換と同じ順番で適用されます(addTransformer
を参照)。 つまり3つのトランスフォーマによってラッパーが適用されると、foo
は$trans3_$trans2_$trans1_foo
のようになります。 ただし、2番目のトランスフォーマでfoo
にラッパーが適用されなかった場合は、$trans3_$trans1_foo
のようになります。 接頭辞のシーケンスを効率的に決定できるようにするため、途中の接頭辞は、そのネイティブでないラッパーが存在する場合にのみ適用されます。 つまりこの例では、$trans1_foo
がネイティブ・メソッドでなくても、$trans1_foo
が存在するため$trans1_
接頭辞が適用されます。- パラメータ:
transformer
- この接頭辞を使用してラップするClassFileTransformer。prefix
- 失敗したネイティブ・メソッド解決を再試行するときに、ラップされたネイティブ・メソッドに適用される接頭辞。 接頭辞がnull
または空の文字列である場合、このトランスフォーマの失敗したネイティブ・メソッド解決は再試行されません。- 例外:
NullPointerException
-null
トランスフォーマを渡した場合。UnsupportedOperationException
- JVMの現在の設定がネイティブ・メソッドの接頭辞(isNativeMethodPrefixSupported()
がfalse)の設定を許可しない場合。IllegalArgumentException
- トランスフォーマが登録されていない場合(addTransformer
を参照)。- 導入されたバージョン:
- 1.6
-
redefineModule
void redefineModule(Module module, Set<Module> extraReads, Map<String,Set<Module>> extraExports, Map<String,Set<Module>> extraOpens, Set<Class<?>> extraUses, Map<Class<?>,List<Class<?>>> extraProvides)モジュールを再定義して、読み込んだモジュールのセット、エクスポートまたは開くパッケージのセット、または使用または提供するサービスを拡張します。 このメソッドは、読み込まれたモジュールのセット、エクスポートまたはオープンされたパッケージ、または使用または提供されるサービスへの変更をインストゥルメンテーションが必要とする、指定されたモジュールのコードのインストゥルメンテーションを容易にします。このメソッドでは、モジュールが読み取るモジュールのセットを減らすことも、エクスポートまたはオープンするパッケージのセットを減らすことも、使用または提供する一連のサービスを減らすこともできません。 名前のないモジュールを再定義するために呼び出されたとき、このメソッドはno-opです。
モジュールが使用または提供するサービスを拡張するときは、サービス型が使用されている各計装サイトでサービス型にアクセスできるようにするために、onusがエージェント上にあります。 このメソッドは、サービス型がモジュールのメンバーであるか、またはモジュールが読み込んだ別のモジュールによってモジュールにエクスポートされたパッケージであるかどうかをチェックしません。
extraExports
パラメータは、エクスポートする追加パッケージのマップです。extraOpens
パラメータは、開く追加パッケージのマップです。 どちらの場合も、マップ・キーは、"java.lang"
など、「Java言語仕様」の6.5.3セクションで定義されているパッケージの完全修飾名です。 マップ値は、パッケージをエクスポートまたはオープンする必要のある空でないモジュールのセットです。extraProvides
パラメータは、モジュールが提供する追加サービス・プロバイダです。 マップ・キーはサービス型です。 マップ値は、実装型の空ではないリストです。各モジュールは、モジュールのメンバーであり、サービスの実装です。このメソッドは同時使用には安全です。したがって、複数のエージェントがほぼ同時に同じモジュールを計測し更新することができます。
- パラメータ:
module
- 再定義するモジュールextraReads
- 読み込める追加のモジュールの空の可能性のあるセットextraExports
- エクスポートする追加パッケージの可能性のある空のマップextraOpens
- オープンする追加パッケージの空のマップextraUses
- 使用する可能性のある追加のサービスの空のセットextraProvides
- 提供する追加サービスの可能性のある空のマップ- 例外:
IllegalArgumentException
-extraExports
またはextraOpens
に、モジュール内のパッケージではないキーが含まれている場合。extraExports
またはextraOpens
がキーを空のセットにマップする場合extraProvides
マップの値に、モジュールのメンバーではないサービス・プロバイダ型またはサービスの実装が含まれている場合。またはextraProvides
がキーを空のリストにマップUnmodifiableModuleException
- モジュールを変更できない場合NullPointerException
- 引数のいずれかがnull
であるか、またはセットまたはマップのいずれかにnull
キーまたは値が含まれている- 導入されたバージョン:
- 9
- 関連項目:
isModifiableModule(Module)
-
isModifiableModule
boolean isModifiableModule(Module module)redefineModule
でモジュールを変更できるかどうかをテストします。 モジュールが変更可能な場合、このメソッドはtrue
を返します。 モジュールが変更可能でない場合、このメソッドはfalse
を返します。 モジュールが名前のないモジュール(名前のないモジュールを再定義することはノー・オペレーションです)である場合、このメソッドは常にtrue
を返します。- パラメータ:
module
- モジュールを変更できるかどうかをテストするモジュール- 戻り値:
- モジュールが変更可能な場合は
true
、それ以外の場合はfalse
- 例外:
NullPointerException
- モジュールがnull
の場合- 導入されたバージョン:
- 9
-