JavaAgent学习之旅(一|静态的premainDemo实例)

一:什么是JavaAgent

     JavaAgent顾名思义就是Java探针技术,我理解的是,通过一个JavaAgent探针类,可以在java虚拟机启动之前,或者运行的时候植入这个探针类,对jvm做一些特别的操作,如动态改变字节码文件这种,要想植入,肯定是通过jvm参数来搞了

     使用JavaAgent的技术的项目我目前知道的是SkyWalking,dubbo用没用我没印象了

二:JavaAgent在JVM运行启动的时候,做一些操作

1.创建一个Java项目,Pure Java Project Only Main method,文件结构如下:

AgentDemoDoMain.Java:

package com.shi;

/**
 * @author DaTou
 * @Description
 * @Date 2020/9/21
 **/
public class AgentDemoDoMain {

    public static void main(String[] args) {
        Test test = new Test();
        new Thread(()->{
            while (true){
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                test.printTest();
            }
        }).start();
    }
}

  Test.java:

package com.shi;

/**
 * @author DaTou
 * @Description
 * @Date 2020/9/21
 **/
public class AgentDemoDoMain {

    public static void main(String[] args) {
        Test test = new Test();
        new Thread(()->{
            while (true){
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                test.printTest();
            }
        }).start();
    }
}

 2.创建一个JavaAgent项目,代码结构如下:

 

 

 

AgentDemo.java--探针代码: 

**其实探针代码是很普通的一个方法,真正需要注意的是MANIFEST.MF文件的配置,项目结构是使用的maven,所以pom的配置对MANIFEST.MF的生成至关重要

package com.shi;

import java.lang.instrument.Instrumentation;

/**
 * @author DaTou
 * @Description
 * @Date 2020/9/21
 **/
public class AgentDemo {

    /**
     * java-agent 静态载入的情况
     * @param agentOps
     * @param instrumentation
     */
    public static void premain(String agentOps, Instrumentation instrumentation) {
        System.out.println("====premain method====");
    }

}

MANIFEST.MF

Manifest-Version: 1.0
Premain-Class: com.shi.AgentDemo

POM.XML:pom的关键是在对maven打包插件的管理上,要说明自己写的MANIFEST.MF文件的位置,maven打包的时候将会忽略这个文件,生成自己的MANIFEST.MF文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.shi</groupId>
    <artifactId>agent-demo</artifactId>
    <version>1.0-SNAPSHOT</version>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
</project>

3.运行项目:

运行AgentDemoDoMain.java中的main方法,加入虚拟机参数(xxxx就是探针包的位置):

-javaagent:xxxxx\agent-demo-1.0-SNAPSHOT.jar

4.结束,本次记录的是java探针技术静态插入的demo,没有很复杂,不涉及对类字节码文件的修改,利用java探针结合字节码的一些工具类如javaassit,可以改变编译后的class文件,实现自己想要的功能,但是javaassit我不会,说白了就是运行了两个main方法而已,一个main一个premain

posted @ 2020-09-21 22:23  大头Tou  阅读(228)  评论(0)    收藏  举报