Javaプローブ-javaagent浅いから深い(二)


この文章は主にmavenツールを通じてjavaagentを構築する方法を紹介します.実質的な原理は同じですが、mavenツールを借りて仕事中の応用シーンに合っているので、簡単に紹介します.同時に、実行時にjavaagentを導入する方法に重点を置きます.
一、mavenツールを利用してjavaagentを構築する
1、mavenプロジェクトの作成
2.前述の方法に従ってAgentクラスを作成し、permain(String,Instrumentation)方法を正しく作成する
3、mavenプロジェクトのpomファイルを作成し、maven-jar-pluginを導入し、パッケージパラメータを正しく構成する
pomファイル:


    4.0.0

    edu.haye
    myagent
    1.0-SNAPSHOT

    
        
            

                org.apache.maven.plugins
                maven-jar-plugin
                2.6
                
                    
                        

                            edu.haye.agents.MyAgent
                        
                    
                
            
            
                org.apache.maven.plugins
                maven-compiler-plugin
                
                    8
                    8
                
            
        
    



[        ]
​

 
4、mvn clean packageコマンドを使用してパッケージ化し、最後にtargetディレクトリの下でjavaagentの要求を満たすjarパッケージを生成します.
二、実行時にjavaagentを導入する
実行時にjavaagentを導入するのは主にVirtualMachineオブジェクトに依存します.このオブジェクトには2つの異なる形式のjavaagentを導入することができます.ここでは、PremainClassと類似した形式で宣言されたjavaagentについて説明します.(プロジェクトにVirtualMachineクラスがない場合は、JDKインストールディレクトリのlib/tools.jarを先に導入する必要があります)
1、Agent-Class類を作成し、要求を満たすコールバック方法を提供する
package edu.haye.agents;

import java.lang.instrument.Instrumentation;
import java.util.Arrays;

/**
 * @author haye
 * @date 10/11/19
 * @description:
 */
public class MyAgent {
    public static void  agentmain(String agentOps,Instrumentation inst){
        System.out.println("--------------agent->agentmain(String Instrumentation) is run------------");
    }
}

Agent−ClassとPremain−Classのエントリメソッドは名前だけが異なり,パラメータタイプは完全に一致していることがわかる.
2、マニフェストリストファイルの作成
Permain-Classと同様に、Agent-ClassプロパティをManifestファイルに書き込んでjavaagentクラスを示す必要があります.ここではmavenツールを使用してpomファイルを作成します.
            

                org.apache.maven.plugins
                maven-jar-plugin
                2.6
                
                    
                        

                            edu.haye.agents.MyAgent
                        
                    
                
            
            

前のラベル改为即可(我的类名是MyAgent)。

3、使用VirtualMachine.attach(String)静态方法获取VirtualMachine的实例对象

attach(String)方法中的参数为目标虚拟机的进程号,可根据实际需求获取,演示代码中使用如下方法进行获取:

        String pid=ManagementFactory.getRuntimeMXBean().getName().split("@")[0];

4、VirtualMachineインスタンスを呼び出すloadAgent(String)メソッドの実行時導入
パラメータはjavaagentのjarパッケージパスで、完全な呼び出しコードは以下の通りです.
package edu.haye;

import com.sun.tools.attach.AgentInitializationException;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;

import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;

/**
 * @author haye
 * @date 10/11/19
 * @description:
 */
public class Main {
    public static void main(String[] args) throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException {
        System.out.println("main method is run");
        String pid=ManagementFactory.getRuntimeMXBean().getName().split("@")[0];//        pid
        VirtualMachine vm = VirtualMachine.attach(pid);//    Jar      
        if(new File("/home/haye/Dev/Code/java/myagent/target/myagent-1.0-SNAPSHOT.jar").exists()){
            vm.loadAgent("/home/haye/Dev/Code/java/myagent/target/myagent-1.0-SNAPSHOT.jar");
        }
    }
}

実行結果:
main method is run
--------------agent->agentmain(String Instrumentation) is run------------

Process finished with exit code 0

*注意事項
1、Manifestファイルには、以前のPermain-Classではなく、Agent-Class属性を含める必要があります.
2、Permain-Classが指定したクラスには、前のpremain(String,Instrumentation)ではなくagentmain(String,Instrumentation)メソッドが含まれます.
3、同じクラスファイルにagentmain(String,Instrumentation)とpremain(String,Instrumentation)を同時に含めることができ、Manifestで両方のロード方式が構成されている場合、両者は共存することができる.
 
上記の内容が不適切であれば教えてください.次の記事では、Instrumentationの使い方を重点的に説明します.