基本的に、私はJVMによってロードされたすべてのクラスをリストするものを作成しようとしています。私が書いたものは動作しますが、それは動作しているjvmでのみ動作します。 私は別のJVMに動的に注入するJavaエージェントを作成しましたが、実際に注入する方法は実際には分かりませんでした。 このエージェントを別のJVMに実際に送信するにはどうすればよいですか? 可能ですか?Java - Javaエージェントを実行中のjvmに挿入する
答えて
あなたが書いた内容を見ることなく支援を提供するのは難しいですが、これはjava.lang.instrument
パッケージのInstrumentation interface(public interface Instrumentation
)という名前のクラスがJavaプログラミング言語コードを計測するのに必要なパッケージを提供していることを通知するだけです。
このクラスで提供されるこのようなメソッドの1つは、ロードされるすべてのクラスを含む配列を返すgetInitiatedClasses
です。ドキュメントを
ルックhere
getInitiatedClasses
クラス[] getInitiatedClasses(クラスローダローダ)
はloaderが起動ローダーであるすべてのクラスの配列を返します。 ローダーがnullの場合、ブートストラップクラス ローダーによって開始されたクラスが返されます。パラメータ:ローダー - 開始クラスリスト 戻り値が返されますローダー:何
がない場合loaderが起動ローダー、長さゼロであるすべてのクラスを含む配列を
HotSpot Attach APIで薬剤を注射することができる。
クラスパスに$JAVA_HOME/lib/tools.jar
の次のスニペットを実行します。
VirtualMachine vm = VirtualMachine.attach(PID);
try {
vm.loadAgent(agentJar);
} finally {
vm.detach();
}
また、あなたは私のコマンドラインjattachユーティリティでこれを行うことがあります。
$ jattach PID load instrument false /path/to/agent.jar
注添付ダイナミックサポートするために、あなたのJavaエージェントがagentmain
方法とMANIFEST.MF
でAgent-Class
性質を持っている必要があること。
私はエージェントに少し問題があります。私は、インストゥルメンテーションエージェントをターゲットJVMとは別にパックするのが最も標準的な方法であると仮定しています。私の 'agentmain()'が呼び出されたとき、私は 'Class.forName(" pkg.name ")'を呼び出すことによってJVMクラスを見つけようとしましたが、常に 'NoClassDefFoundError'を返しています。私はここに質問を掲載しました(https://stackoverflow.com/questions/46523055/using-class-forname-in-java-instrumentation-agent?noredirect=1#comment80003396_46523055);ここにあります。私は、エージェントがVMに接続されていても、そのクラスを参照できない理由を少し混乱させます。 – ha9u63ar
ダイナミックエージェントは、ターゲットVM内のアタッチ時に実行されるagentmain(String, Instrumentation)
メソッドを宣言する必要があります。 tools.jar(Java 9まで)依存関係は、JDKにのみ含まれていますが、JREには含まれていません。ただし、エージェントプログラムをJDKにバンドルしてそこからJVMにアタッチすることはできます。
最大の落とし穴は、異なるVMでAPIが異なることです。しかし、異なるVM用に異なる実装を含むbyte-buddy-agentのようなライブラリを使うことができます。これは、ID 私-IDでJavaプロセスにmy.jarに含まれているエージェントを添付
ByteBuddyAgent.attach("my.jar", "my-pid");
:添付ファイルをすることによって行うことでしょう。
は、私の知る限りthe commentから理解として、あなたは別のJavaプロセス内からリモートJVMを検査することができます何かに興味を持っています。その場合は、JavaエージェントではなくServiceability Agentが必要です。
は、別のJVMプロセスに接続して、そのメモリを読み込み、VM構造を再構築し、リモートオブジェクトを反射的に検査することができます。ここで
は、リモートJVMによってロードされたすべてのクラスを一覧表示するためのサンプルツールです:
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;
public class ListRemoteClasses extends Tool {
public static void main(String[] args) {
new ListRemoteClasses().execute(args);
}
@Override
public void run() {
VM.getVM().getSystemDictionary().classesDo(klass -> {
String className = klass.getName().asString().replace('/', '.');
System.out.println(className);
});
}
}
それを実行する方法:
java -cp $JAVA_HOME/lib/sa-jdi.jar:. ListRemoteClasses PID
- 1. 実行中のJVMでデバッグを有効にするJava API
- 2. JavaエージェントがJVMにロードされない
- 3. LinkedListの中にJavaを挿入する
- 4. 複数のJavaエージェントの同時実行
- 5. 別のJVMのJavaデスクトップアプリケーション内からJava mainメソッドを実行
- 6. 実行時にJavaのjvmプロパティを設定するには
- 7. apache flumeのエージェントを実行中
- 8. Java実行中エラー
- 9. 別のサーバー/ JVM上でJavaスレッドを実行する
- 10. JVMでJNIベースの.jarを実行中
- 11. Javaでバットファイルを実行中
- 12. java実行中のLinuxコマンド
- 13. 実行中のJavaアプリケーション
- 14. 別のJavaプログラムの中でJavaプログラムを実行する方法
- 15. Javaエージェントのデバッグ
- 16. レコードを挿入中にJDBC Javaでエラーが発生する
- 17. Java Selenium pararelテストケース実行中
- 18. Java内からJVMを実行してJavaソースファイルをコンパイルします
- 19. Java挿入ソート
- 20. Javaでの改行文字の挿入
- 21. MySQL Javaの挿入
- 22. Javaスクリプトデータベースの挿入
- 23. 実行中のJavaアプリケーションでjarアーカイブを実行する
- 24. JavaコードをTextViewに挿入
- 25. 既存のクエリの実行中に列を挿入する
- 26. AndroidでJavaバイトコードを実行する - DalvikVMの上にあるSun JVM
- 27. 1.6 JVMで実行中のJettyはJava 1.6でコンパイルされたwebappを実行できません
- 28. 配列をJavaの行として配列に挿入する
- 29. Java:複数の行をMySQLに挿入する
- 30. Javaで実行可能ファイルを実行中に落とす
私はこのことを認識しています。問題は、jarファイルがすでに実行されており、javaagentを接続する必要があることです。 – Stoud