パッケージjava.lang.instrument
エージェントを構成するクラス・ファイルは、実行可能JAR内のアプリケーションとともに、または「エージェントJAR」という個別のJARファイルとして、JARファイルにパッケージ化されます。 JARファイルのメイン・マニフェスト内の属性は、JARファイル内のクラス・ファイルの1つを「エージェント・クラス」として識別します。 エージェント・クラスは、JVMがエージェントをstartに起動する特別なメソッドを定義します。
実行可能JAR内のアプリケーションとともにパッケージ化されたエージェントは、JVMの統計時に起動されます。 エージェントJARファイルにパッケージ化されているエージェントは、コマンドライン・オプションを介してJVMの起動時に、または実装がサポートしている場所で、実行中のJVMで起動できます。
エージェントは、ロード時に任意の方法でクラスを変換したり、モジュールを変換したり、すでにロードされているクラスのメソッドのバイトコードを変換できます。 エージェントのデプロイ、アプリケーションとエージェントをパッケージ化するアプリケーションのデプロイ、または実行中のアプリケーションにエージェントをロードするツールの使用を行う開発者または管理者は、エージェントJARファイルの内容や構造を含む各エージェントの信頼性の検証を担当します。
エージェントの起動
実行可能JARファイル内のアプリケーションとともにパッケージ化されたエージェントの起動
「JARファイルの仕様」は、「実行可能なJARファイル」としてパッケージ化されたスタンドアロン・アプリケーションのマニフェスト属性を定義します。 実装が、アプリケーションを実行可能なJARとして起動するメカニズムをサポートしている場合、JARファイルのメイン・マニフェストにLauncher-Agent-Class
属性を含めて、アプリケーションにパッケージ化されたJavaエージェント・クラスのバイナリ名を指定できます。 属性が存在する場合、JVMはエージェント・クラスをロードし、そのagentmain
メソッドを呼び出して、エージェントを起動します。 このメソッドは、アプリケーションのmain
メソッドが呼び出される前に呼び出されます。 agentmain
メソッドには、2つの可能なシグネチャのいずれかがあります。 JVMはエージェント・クラスで最初に次のメソッドを呼び出そうとします。
public static void agentmain(String agentArgs, Instrumentation inst)
エージェント・クラスがこのメソッドを定義しない場合、JVMは次のメソッドを呼び出そうとします:
public static void agentmain(String agentArgs)
agentArgs
パラメータの値は、常に空の文字列です。 最初のメソッドでは、inst
パラメータは、エージェントがコードのインストゥルメントに使用できるInstrumentation
オブジェクトです。
agentmain
メソッドは、エージェントを起動して戻すために必要な初期化を行う必要があります。 エージェントを起動できない場合(たとえば、エージェント・クラスをロードできない場合、エージェント・クラスが適合agentmain
メソッドを定義していない場合、またはagentmain
メソッドが捕捉されない例外またはエラーをスローした場合)、JVMはアプリケーションのmain
メソッドが呼び出される前に中断されます。
コマンドライン・インタフェースからのエージェントの起動
実装でコマンドライン・インタフェースからエージェントを起動する手段が提供されている場合、エージェントJARは次のコマンドライン・オプションを介して指定されます:
-javaagent:<jarpath>[=<options>]
<jarpath>
はエージェントのJARファイルへのパス、<options>
はエージェントのオプションです。
エージェントJARファイルのメイン・マニフェストには、属性 Premain-Class
が含まれている必要があります。 この属性の値は、JARファイル内のエージェント・クラスのバイナリ名です。 JVMは、エージェント・クラスをロードし、そのpremain
メソッドを呼び出して、エージェントを起動します。 このメソッドは、アプリケーションのmain
メソッドが呼び出される前に呼び出されます。 premain
メソッドには2つのシグネチャのうちのいずれかがあります。 JVMはエージェント・クラスで最初に次のメソッドを呼び出そうとします。
public static void premain(String agentArgs, Instrumentation inst)
エージェント・クラスがこのメソッドを定義しない場合、JVMは次のメソッドを呼び出そうとします:
public static void premain(String agentArgs)
エージェントは、agentArgs
パラメータ経由でエージェント・オプションが渡されます。 エージェント・オプションは単一の文字列として渡され、追加の解析はエージェント自身によって行われます。 最初のメソッドでは、inst
パラメータは、エージェントがコードのインストゥルメントに使用できるInstrumentation
オブジェクトです。
エージェントを起動できない場合(たとえば、エージェント・クラスをロードできない場合、エージェント・クラスが適合premain
メソッドを定義していない場合、または premain
メソッドが捕捉されない例外またはエラーをスローした場合)、JVMはアプリケーションのmain
メソッドが呼び出される前に中止されます。
実装がコマンド行インタフェースからエージェントを開始する方法を提供する必要はありません。 実行されると、上記で指定された-javaagent
オプションがサポートされます。 -javaagent
オプションは、同じコマンドラインで複数回使用することができ、複数のエージェントを起動します。 premain
メソッドは、エージェントがコマンドラインで指定された順序で呼び出されます。 複数のエージェントが同じ<jarpath>
を使用できます。
エージェント・クラスには、実行中のJVM (下記参照)でエージェントを起動するときに使用するagentmain
メソッドもあります。 コマンド行オプションを使用してエージェントを開始した場合は、agentmain
メソッドが呼び出されません。
実行中のJVMでのエージェントの起動
実装では、実行中のJVM (JVM起動後の意味)でエージェントを起動するメカニズムを提供できます。 この開始方法の詳細は実装固有ですが、通常はアプリケーションがすでに起動しており、そのmain
メソッドがすでに起動されています。 実行中のJVMでエージェントの起動が実装でサポートされている場合、次のことが適用されます:
エージェント・クラスは、エージェントJARファイルにパッケージ化する必要があります。 エージェントJARファイルのメイン・マニフェストには、属性
Agent-Class
が含まれている必要があります。 この属性の値は、JARファイル内のエージェント・クラスのバイナリ名です。エージェント・クラスは、public static
agentmain
メソッドを定義する必要があります。JVMは、実行中のJVMで起動しようとする各エージェントの標準エラー・ストリームに警告を出力します。 エージェントが以前に (JVMの起動時または実行中のJVMで起動時)を起動していた場合は、同じエージェントを2回目以降に起動しようとしたときに警告が出力されるかどうかに固有の実装です。 警告は、実装固有のコマンド行オプションによって無効にできます。
実装に関するノート: HotSpot VMでは、JVMオプション
-XX:+EnableDynamicAgentLoading
を使用して、実行中のJVMにエージェントを動的にロードできるようにオプトインします。 このオプションは、実行中のJVMでエージェントを起動する際の標準エラーに対する警告を抑制します。
JVMは、エージェント・クラスをロードし、その agentmain
メソッドを呼び出して、エージェントを起動します。 agentmain
メソッドには、2つの可能なシグネチャのいずれかがあります。 JVMはエージェント・クラスで最初に次のメソッドを呼び出そうとします。
public static void agentmain(String agentArgs, Instrumentation inst)
エージェント・クラスがこのメソッドを定義しない場合、JVMは次のメソッドを呼び出そうとします:
public static void agentmain(String agentArgs)
エージェントは、agentArgs
パラメータ経由でエージェント・オプションが渡されます。 エージェント・オプションは単一の文字列として渡され、追加の解析はエージェント自身によって行われます。 最初のメソッドでは、inst
パラメータは、エージェントがコードのインストゥルメントに使用できるInstrumentation
オブジェクトです。
agentmain
メソッドでは、エージェントの開始に必要な必須の初期化を実行するようにしてください。 開始が完了すると、メソッドを返すようにします。 エージェントを開始できない場合(たとえばエージェント・クラスをロードできなかったため、またはエージェント・クラスに適切なagentmain
メソッドがないため)、JVMは異常終了します。 agentmain
メソッドがキャッチされない例外をスローすると、(トラブルシューティングの目的でJVMによって記録されることがあります)は無視されます。
エージェント・クラスには、コマンドライン・オプションを使用してエージェントを起動するときに使用するpremain
メソッドもあります。 premain
メソッドは、実行中のJVMでエージェントが起動されるときに起動されません。
エージェント・クラスで利用可能なエージェント・クラスとモジュール/クラスの読み込み
エージェントJARファイルからロードされたクラスは、「システム・クラス・ローダー」によってロードされ、システム・クラス・ローダーの「名前のないモジュール」のメンバーです。 システム・クラス・ローダーは、通常、アプリケーションmain
メソッドも含むクラスを定義します。
エージェント・クラスに表示されるクラスは、システム・クラス・ローダーに表示されるクラスであり、最小限には次のものが含まれます:
「ブート層」のモジュールによってエクスポートされるパッケージ内のクラス。 ブート・レイヤーにすべてのプラットフォーム・モジュールが含まれているかどうかは、初期モジュールやアプリケーションの起動方法によって異なります。
システム・クラス・ローダー(通常はクラスパス)がその名前のないモジュールのメンバーであると定義できるクラス。
エージェントが、ブートストラップ・クラス・ローダーによって定義されて、名前の付いていないモジュールのメンバーとなるように手配するすべてのクラス。
エージェント・クラスがブート・レイヤーにないプラットフォーム(その他)モジュールのクラスにリンクする必要がある場合は、これらのモジュールがブート・レイヤー内にあることを保証する方法でアプリケーションを起動する必要があります。 たとえば、JDKの実装では、--add-modules
コマンドライン・オプションを使用して、起動時に解決するルート・モジュールのセットにモジュールを追加できます。
エージェントがブートストラップ・クラス・ローダー(appendToBootstrapClassLoaderSearch
または以下に指定されたBoot-Class-Path
属性を使用して)によってロードされるようにレンジするサポート・クラスは、ブートストラップ・クラス・ローダーに定義されたクラスにのみリンクする必要があります。 すべてのプラットフォーム・クラスがブート・クラス・ローダーによって定義できるという保証はありません。
カスタム・システム・クラス・ローダーが(getSystemClassLoader
メソッドで指定されたシステム・プロパティjava.system.class.loader
を使用して)で構成されている場合は、appendToSystemClassLoaderSearch
で指定されているappendToClassPathForInstrumentation
メソッドを定義する必要があります。 つまり、カスタム・システム・クラス・ローダーは、エージェントJARファイルをシステム・クラス・ローダーの検索に追加するためのメカニズムをサポートしなければなりません。
JARファイル・マニフェスト属性
アプリケーションまたはエージェントのJARファイル・マニフェストのメイン・セクションにある次の属性は、Javaエージェントに対して定義されます:
Launcher-Agent-Class
- 実行可能なJARファイルでアプリケーションを起動するメカニズムが実装でサポートされている場合、この属性が存在する場合は、アプリケーションにパッケージ化されているエージェント・クラスのバイナリ名を指定します。 エージェントは、エージェント・クラスの
agentmain
メソッドを起動して起動します。 これは、アプリケーションのmain
メソッドが呼び出される前に呼び出されます。Premain-Class
- エージェントJARがJVMの起動時に指定されている場合、この属性はJARファイル内のエージェント・クラスのバイナリ名を指定します。 エージェントは、エージェント・クラスの
premain
メソッドを起動して起動します。 これは、アプリケーションのmain
メソッドが呼び出される前に呼び出されます。 この属性が存在しない場合、JVMは異常終了します。Agent-Class
- JVMの起動後のある時点でエージェントを起動するメカニズムが実装でサポートされている場合、この属性はエージェントJARファイル内のJavaエージェント・クラスのバイナリ名を指定します。 エージェントは、エージェント・クラスの
agentmain
メソッドを起動して起動します。 この属性は必須です。存在しない場合、エージェントは起動されません。Boot-Class-Path
- ブートストラップ・クラス・ローダーで検索されるパスのリストです。 パスはディレクトリまたはライブラリを表します。多くのプラットフォームでは、通常、JARファイルまたはzipライブラリとして参照されます。 クラスを検索するプラットフォーム固有のメカニズムが失敗すると、これらのパスがブートストラップ・クラス・ローダーで検索されます。 パスはリストの順序で検索されます。 リスト内のパスは1つ以上の空白文字で区切られます。 パスの構文は、階層型URIのパス・コンポーネントの構文になります。 スラッシュ文字(/)で始まると絶対パス、それ以外の場合は相対パスです。 相対パスはエージェントのJARファイルの絶対パスに対して解決されます。 パスが不正または存在しない場合は無視されます。 JVMの起動後のある時点でエージェントが起動されると、JARファイルを表さないパスは無視されます。 この属性はオプションです。
Can-Redefine-Classes
- ブール値(
true
またはfalse
、大文字小文字は区別しない)。 クラスを再定義する機能がこのエージェントに必要かを表します。true
以外の値はfalse
であるとみなされます。 この属性はオプションで、デフォルトはfalse
です。Can-Retransform-Classes
- ブール値(
true
またはfalse
、大文字小文字は区別しない)。 クラスを再変換する機能がこのエージェントに必要かを表します。true
以外の値はfalse
であるとみなされます。 この属性はオプションで、デフォルトはfalse
です。Can-Set-Native-Method-Prefix
- ブール値(
true
またはfalse
、大文字小文字は区別しない)。 ネイティブ・メソッドの接頭辞を設定する機能がこのエージェントに必要かを表します。true
以外の値はfalse
であるとみなされます。 この属性はオプションで、デフォルトはfalse
です。
エージェントJARファイルでは、マニフェスト内にPremain-Class
属性と Agent-Class
属性の両方が存在することがあります。 -javaagent
オプションを使用してエージェントをコマンドラインで起動すると、 Premain-Class
属性でエージェント・クラスのバイナリ名が指定され、 Agent-Class
属性は無視されます。 同様に、JVMの起動後のある時点でエージェントが起動された場合、Agent-Class
属性は、エージェント・クラス(Premain-Class
属性の値は無視されます)のバイナリ名を指定します。
モジュール内でコードを計測
ブートストラップ・クラス・ローダーの検索パスにサポート・クラスをデプロイするエージェント、またはメイン・エージェント・クラスをロードするクラス・ローダーの検索パスとして、Java仮想マシンは、変換されたクラスのモジュールを、両方のクラス・ローダーの名前のないモジュールを読み取るように配置します。
- 導入されたバージョン:
- 1.5
-
クラス説明このクラスは、
Instrumentation.redefineClasses
メソッドに対するパラメータ・ブロックとして機能します。クラス・ファイルのトランスフォーマ。入力パラメータが無効な場合にClassFileTransformer.transform
の実装によってスローされます。このクラスは、Javaプログラミング言語コードを計測するためのサービスを提供します。指定されたクラスの1つを変更できない場合、Instrumentation.redefineClasses
の実装によってスローされます。モジュールを変更できないことを示すためにスローされます。