java · 2024-01-17 0

javaagent 使用

一、javaagent

1.maven 依赖

<groupId>org.example</groupId>
<artifactId>agent-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.21.0-GA</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.4</version>
            <executions>
                <execution>
                    <id>shade-when-package</id>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <artifactSet>
                            <includes>
                                <include>org.javassist:javassist</include>
                            </includes>
                        </artifactSet>
                        <shadeSourcesContent>true</shadeSourcesContent>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                    </manifest>
                    <manifestEntries>
                        <Agent-Class>com.example.agent.PremainAgent</Agent-Class>
                        <Premain-Class>com.example.agent.PremainAgent</Premain-Class>
                        <Can-Redefine-Classes>true</Can-Redefine-Classes>
                        <Can-Retransform-Classes>true</Can-Retransform-Classes>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

2.agent 类

public class PremainAgent {

    public static void premain(String agentOps, Instrumentation inst) {
        inst.addTransformer(new DefineTransformer());
    }

    private static class DefineTransformer implements ClassFileTransformer {

        public final String INJECTED_CLASS_NAME = "com.example.Person";

        public final String METHOD_NAME = "sayHello";

        @Override
        public byte[] transform(ClassLoader loader, String className,
                                Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
                                byte[] classfileBuffer) throws IllegalClassFormatException {
            className = className.replace("/", ".");
            if (INJECTED_CLASS_NAME.equals(className)) {
                try {
                    CtClass ctclass = ClassPool.getDefault().get(className);
                    CtMethod ctmethod = ctclass.getDeclaredMethod(METHOD_NAME);

                    // ctmethod.insertBefore("System.out.println(11111111);");

                    // 构建新的方法体
                    StringBuilder bodyStr = new StringBuilder();
                    bodyStr.append("{");
                    bodyStr.append("return 200;");
                    bodyStr.append("}");

                    ctmethod.setBody(bodyStr.toString());
                    return ctclass.toBytecode();
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
            return classfileBuffer;
        }
    }
}

3.打包成 jar

mvn package

打包成 jar 包,agent-demo-1.0-SNAPSHOT.jar

二、使用

1.maven 依赖

<groupId>org.example</groupId>
<artifactId>java-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <!--<version>2.4</version>-->
            <configuration>
                <archive>
                    <addMavenDescriptor>false</addMavenDescriptor>
                    <manifest>
                        <mainClass>com.example.Main</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

2.Main 类

public class Person {

    public int sayHello() {
        // System.out.println("hello");
        return 1;
    }
}
public class Main {

    public static void main(String[] args) {
        Person person = new Person();
        int result = person.sayHello();
        System.out.println(result);
    }
}

3.打包

mvn package

4.测试

zxm@zxm-pc:~/IdeaProjects/java-demo$ java -javaagent:agent-demo-1.0-SNAPSHOT.jar -jar target/java-demo-1.0-SNAPSHOT.jar
200