如何编写一个javaAgent jar工具包超详细教程

介绍

Java Agent技术

Java Agent技术是JDK提供的用来编写Java工具的技术,使用这种技术生成一种特殊的jar包,这种jar包可以让Java程序
运行其中的代码。
在这里插入图片描述
在这里插入图片描述

Java Agent技术的两种模式

Java Agent技术实现了让Java程序执行独立的Java Agent程序中的代码,执行方式有两种:
⚫ 静态加载模式
⚫ 动态加载模式

Java Agent技术的两种模式 - 静态加载模式

静态加载模式可以在程序启动的一开始就执行我们需要执行的代码,适合用APM等性能监测系统从一开始就监控程序
的执行性能。静态加载模式需要在Java Agent的项目中编写一个premain的方法,并打包成jar包。
在这里插入图片描述
接下来使用以下命令启动Java程序,此时Java虚拟机将会加载agent中的代码并执行
在这里插入图片描述
premain方法会在主线程中执行:

在这里插入图片描述

Java Agent技术的两种模式 – 动态加载模式

动态加载模式可以随时让java agent代码执行,适用于Arthas等诊断系统。动态加载模式需要在Java Agent的项目中编
写一个agentmain的方法,并打包成jar包
在这里插入图片描述
接下来使用以下代码就可以让java agent代码在指定的java进程中执行了。
在这里插入图片描述
agentmain方法会在独立线程中执行:
在这里插入图片描述

搭建java agent静态加载模式的环境

步骤:

1、创建maven项目,添加maven-assembly-plugin插件,此插件可以打包出java agent的jar包。
2、编写类和premain方法,premain方法中打印一行信息。
3、编写MANIFEST.MF文件,此文件主要用于描述java agent的配置属性,比如使用哪一个类的
premain方法。
4、使用maven-assembly-plugin进行打包。
5、创建spring boot应用,并静态加载上一步打包完的java agent。

步骤1-4
代码(使用jdk17编辑):
目录结构:
在这里插入图片描述

maven 项目 pom.xml 文件(关注代码点插件位置)

<?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>org.example</groupId>
    <artifactId>itheima-agent</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
<build>
    <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <!--将所有依赖都打入同一个jar包中-->
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <!--指定java agent相关配置文件-->
                     <archive>
                         <manifestFile>src/main/resources/MANIFEST.MF</manifestFile>
                     </archive>
                </configuration>
            </plugin>
    </plugins>
</build>

</project>

AgenMain.java

package com.zss.javaagent;

import java.lang.instrument.Instrumentation;

public class AgenMain {
    // premain方法
    public static void premain(String agentArgs, Instrumentation inst){
        System.out.println("【remain执行了】");
    }
    // premain方法
    public static void agentmain(String agentArgs, Instrumentation inst){
        System.out.println("【agentmain执行了】");
    }
}

MANIFEST.MF

Manifest-Version: 1.0
Premain-Class: com.zss.javaagent.AgenMain
Agent-Class: com.zss.javaagent.AgenMain
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Can-Set-Native-Method-Prefix: true

进行打包在这里插入图片描述
步骤5:
创建springboot项目在这里插入图片描述

JavaAgentTestController.java

package com.example.testdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * java -jar -javaagent:D:/jvm/itheima-jvm-java-agent-jar-with-dependencies.jar  .\spring-boot-demo-0.0.1-SNAPSHOT.jar
 */
@RestController
@Controller
public class JavaAgentTestController {

    @GetMapping("/test1")
    public String test1(String name) {
        return "test1";
    }
}

TestdemoApplication.java

package com.example.testdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.nio.ByteBuffer;

@SpringBootApplication
public class TestdemoApplication {

    public static void main(String[] args) {
        System.out.println("main方法执行了...");
        SpringApplication.run(TestdemoApplication.class, args);
    }

}

pom文件中我只添加了这个依赖

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

打包操作在这里插入图片描述
启动jar包
在这里插入图片描述

java -jar .\testdemo-0.0.1-SNAPSHOT.jar

此时日志只显示main方法执行了…
退出程序 Ctrl+c
如何启动jar包之前启动agent连接到jar包呢(需要再通过java agent命令将jar包引入进来)
右键复制刚才agent jar包的绝对路径
在这里插入图片描述
在这里插入图片描述
可以发现已经打印出了agent包里面写的方法了
在这里插入图片描述
命令:

java -jar -javaagent:E:\IEDA_DEMO\Study\jvm\javaagent\itheima-agent\target\itheima-agent-1.0-SNAPSHOT-jar-with-dependencies.jar  .\testdemo-0.0.1-SNAPSHOT.jar

上面是操作agent静态加载到jar包当中,下面我们来看看动态加载

搭建java agent动态加载模式的环境

步骤:

1、创建maven项目,添加maven-assembly-plugin插件,此插件可以打包出java agent的jar包。
2、编写类和agentmain方法, agentmain方法中打印一行信息。
3、编写MANIFEST.MF文件,此文件主要用于描述java agent的配置属性,比如使用哪一个类的
agentmain方法。
4、使用maven-assembly-plugin进行打包。
5、编写main方法,动态连接到运行中的java程序。

首先刚才的启动springboot项目
在这里插入图片描述
打开cmd 使用jps 插看当前springboot程序的进程ID记录下来
在这里插入图片描述
进程ID为:28712

在这里插入图片描述
新建一个类为:AttachMain.java 将刚才查看的进程ID复制到
下面这段代码里,另一个需要填写的则是agent jar包的绝对路径

package com.zss.javaagent;

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.IOException;

public class AttachMain {
    public static void main(String[] args) throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException {
        //获取进程虚拟机对象  
        VirtualMachine attach = VirtualMachine.attach("28712");
          // 执行 java agent 里面的agentmain 方法(所以需要找到jar包的路径)
        attach.loadAgent("E:\\IEDA_DEMO\\Study\\jvm\\javaagent\\itheima-agent\\target\\itheima-agent-1.0-SNAPSHOT-jar-with-dependencies.jar");
     }
}

执行下main方法试试
这个项目扫描都没有输出(因为这个链接的进程是隔壁springboot项目可以去隔壁看看)
在这里插入图片描述

在这里插入图片描述

执行五次看看
在这里插入图片描述

是不是有点arthas连接已运行的程序并执行代码的味道了。

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
opentelemetry-javaagent.jar一个用于自动化和 Java 应用程序的分布式跟踪的工具。我们可以使用自定义 instrument 来扩展其功能。 自定义 instrument 可以帮助我们实现一些自定义的行为,例如,我们可以在代码中插入额外的标记信息,或者在特定的函数或方法中加入额外的追踪逻辑。 要实现自定义 instrument,我们需要进行以下步骤: 1. 创建一个 Java 类,并继承 `OtelInstrumenter` 类。这是一个由 OpenTelemetry 提供的接口,用于定义自定义 instrument 的行为。 2. 在该类中,我们需要实现 `applyInstrumentation` 方法。该方法会被调用来应用自定义的 instrument 到目标应用程序中。 3. 在 `applyInstrumentation` 方法中,我们可以使用 OpenTelemetry 提供的 API 来修改目标应用程序的代码,例如,在特定的函数或方法调用前后插入追踪代码。 4. 编译并打包自定义 instrument 的代码,并将其作为 `-javaagent` 参数传递给 `opentelemetry-javaagent.jar`。当目标应用程序启动时,这个自定义 instrument 会被加载和应用。 通过使用自定义 instrument,我们可以根据自己的需求对目标应用程序的代码进行修改和增强。这样,我们就能够更好地实现跟踪和监控,并获得更加详细和准确的跟踪数据。 总结起来,opentelemetry-javaagent.jar 提供了一种灵活和可扩展的方式来实现自定义 instrument。我们可以通过创建自定义 instrument 类,并在其中实现特定的逻辑来修改目标应用程序的代码,从而实现更精确和详细的分布式跟踪。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值