当前位置: 首页 > news >正文

java agent的使用【通俗易懂版】

一、静态代理Agent
1.生成Agent的jar包
(1)创建Agent项目,引入javassist.jar包
(2)编写premain方法

import java.lang.instrument.Instrumentation;public class Agent1 {public static void premain(String agentArgs, Instrumentation inst) {System.out.println("agentArgs : " + agentArgs);MyAgentTransfer trans = new MyAgentTransfer();MyAgentTransferboot trans_boot = new MyAgentTransferboot();inst.addTransformer(trans, true);inst.addTransformer(trans_boot, true);}}

(3)创建MyAgentTransferboot类,实现ClassFileTransformer接口,重写transform方法

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CodeConverter;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import javassist.expr.ExprEditor;
import javassist.expr.MethodCall;public class MyAgentTransferboot implements ClassFileTransformer{/** ClassLoader loader: 类加载器,用于加载当前类的类。 String className: 正在加载的类的名称(用斜杠分隔的形式,例如 java/lang/String)。Class<?> classBeingRedefined: 如果这个类正在被重新定义,则为其对应的 Class 对象;否则为 null。 ProtectionDomain protectionDomain: 类的保护域,提供关于类的安全权限的信息。byte[] classfileBuffer: 原始的字节码数组。 */@Overridepublic byte[] transform(ClassLoader loader, String className,Class<?> classBeingRedefined, ProtectionDomain protectionDomain,byte[] classfileBuffer) throws IllegalClassFormatException {byte[] transformed = null;  
//        System.out.println("Transforming className::" + className);  if(!className.contains("TaxController") || !className.contains("")) {return classfileBuffer;}ClassPool pool = null;  CtClass cl = null;  try {  pool = ClassPool.getDefault();cl = pool.makeClass(new java.io.ByteArrayInputStream(classfileBuffer));  
//            CtMethod aop_method = pool.get("com.jdktest.instrument.AopMethods").
//                    getDeclaredMethod("aopMethod");
//            System.out.println(aop_method.getLongName());CodeConverter convert = new CodeConverter();if (cl.isInterface() == false) {  CtMethod[] methods = cl.getDeclaredMethods();  for (int i = 0; i < methods.length; i++) {  if (methods[i].isEmpty() == false) {  // AOPInsertMethod(methods[i]);  if(methods[i].getName().contains("getUrl") ) {System.out.println("methods[i].getName::" + methods[i].getName());  String name =  methods[i].getName();methods[i].insertAt(92, "System.out.println(\"---------------Url:\" + Url);");
//                        	methods[i].insertBefore(" System.out.println(\"TTTTTTTTTTTTTTTTTT**********************************************" +name + "\");");
//                        	methods[i].insertBefore(" return \"100\";");}}  }  transformed = cl.toBytecode();  }  } catch (Exception e) {  System.err.println("Could not instrument  " + className  + ",  exception : " + e.getMessage());  } finally {  if (cl != null) {  cl.detach();  }  }  return transformed;  }private void AOPInsertMethod(CtMethod method) throws NotFoundException,CannotCompileException {method.instrument(new ExprEditor() {  @Overridepublic void edit(MethodCall m) throws CannotCompileException {  m.replace("{ long stime = System.currentTimeMillis(); $_ = $proceed($$);System.out.println(\""+ m.getClassName() + "." + m.getMethodName()+ " cost:\" + (System.currentTimeMillis() - stime) + \" ms\");}");}}); 
//      method.insertBefore("System.out.println(\"enter method\");");
//      method.insertAfter("System.out.println(\"leave method\");");}

(4)将Agent项目进行打包

在这里插入图片描述
在这里插入图片描述

(5)用压缩包方式打开生成的jar包,打开\META-INF\MANIFEST.MF文件,添加如下代码:

Can-Redefine-Classes: true
Can-Retransform-Classes: true
Premain-Class: com.javaAgent.Agent1

2.在项目中使用agent
在这里插入图片描述
在这里插入图片描述

命令:-javaagent:jar包地址=参数
如:-javaagent:D:\Work_Code\javaAgent\StringLenAgent.jar=‘1’
-javaagent:D:\Work_Code\javaAgent\StringLenAgent.jar

二、动态代理Attach
1.生成Attach的jar包
(1)创建Attach项目,引入javassist.jar包、com.sun.tools.attach-1.8.0_jdk8u172-b11.jar包
(2)编写agentmain方法

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;public class Attach1 {public static void agentmain(String attachArgs, Instrumentation instrumentation) {System.out.println("attach agentmain启动");System.out.println("attachArgs : " + attachArgs);Class<?>[] classes = instrumentation.getAllLoadedClasses();for (Class<?> cls : classes) {String className = cls.getName();if(className.contains("TaxController")) {CtClass ctClass;try {ClassPool classPool = ClassPool.getDefault();ctClass = classPool.get(className);CtMethod[] methods = ctClass.getDeclaredMethods();  for (int i = 0; i < methods.length; i++) {  if (methods[i].isEmpty() == false) {  // AOPInsertMethod(methods[i]);  if(methods[i].getName().contains("getUrl") ) {System.out.println("methods[i].getName::" + methods[i].getName());  String name =  methods[i].getName();methods[i].insertAt(92, "System.out.println(\"---------------Url:\" + Url);");
//                            	methods[i].insertBefore(" System.out.println(\"TTTTTTTTTTTTTTTTTT**********************************************" +name + "\");");
//                            	methods[i].insertBefore(" return \"100\";");}}  }  ClassDefinition classDefinition = new ClassDefinition(cls, ctClass.toBytecode());instrumentation.redefineClasses(classDefinition);} catch (Throwable e) {System.out.println(e.getMessage());e.printStackTrace();}}

(3)将Attach项目进行打包
(4)用压缩包方式打开生成的jar包,打开\META-INF\MANIFEST.MF文件,添加如下代码:
Agent-Class: com.javaAttach.Attach1
Can-Redefine-Classes: true
Can-Retransform-Classes: true
(5)启动需被代理的应用程序
编写main方法,给需被代理的应用程序添加代理

import java.util.concurrent.TimeUnit;
import com.sun.tools.attach.*;public class AttachUseMain {public static void main(String[] args) throws Exception{System.out.println("AttachUseMain启动");long start = System.currentTimeMillis();System.out.println(start);for (VirtualMachineDescriptor vmd : VirtualMachine.list()) {String name = vmd.displayName();System.out.println(name + ":" + vmd.id());if (name.contains("Application")) {VirtualMachine vm = VirtualMachine.attach(vmd.id());
//                vm.loadAgent("D:\\Work_Code\\javaAgent\\StringLenAttach.jar=hello,ok,aa,bb,cc=3");vm.loadAgent("D:\\Work_Code\\javaAgent_1\\javaAttach\\StringLenAttach004.jar=22");TimeUnit.MINUTES.sleep(1);vm.detach();System.out.println("Agent 已成功附加到目标 JVM");}}long end = System.currentTimeMillis();System.out.println(end - start);
//        String targetPid = "25304"; //jps -l
//        // 指定要附加的 Agent JAR 路径
//        String agentPath = "D:\\Work_Code\\javaAgent\\StringLenAttach.jar";
//
//        // 附加到目标 JVM
//        VirtualMachine vm = VirtualMachine.attach(targetPid);
//        // 加载 Agent
//        vm.loadAgent(agentPath);
//        // 断开连接
//        vm.detach();System.out.println("over");}
}

相关文章:

java agent的使用【通俗易懂版】

一、静态代理Agent 1&#xff0e;生成Agent的jar包 &#xff08;1&#xff09;创建Agent项目&#xff0c;引入javassist.jar包 &#xff08;2&#xff09;编写premain方法 import java.lang.instrument.Instrumentation;public class Agent1 {public static void premain(Stri…...

大模型学习指南

随着人工智能的迅猛发展&#xff0c;大模型成为了技术前沿的璀璨明星。踏入大模型学习领域&#xff0c;需要在多个关键方面下功夫。 扎实的数学功底是基石。线性代数为理解多维数据、矩阵运算提供支撑&#xff0c;像大模型中权重矩阵的处理就离不开它&#xff1b;概率论与数理…...

单片机:实现定时器中断(数码管读秒+LED闪烁)(附带源码)

单片机实现定时器中断&#xff1a;数码管读秒与LED闪烁 在单片机项目中&#xff0c;定时器中断是一个常见的应用&#xff0c;用于实现定时任务&#xff0c;例如定时更新显示或控制周期性事件。本文将介绍如何使用定时器中断实现数码管读秒和LED闪烁功能。通过使用定时器中断&a…...

STM32单片机芯片与内部33 ADC 单通道连续DMA

目录 一、ADC DMA配置——标准库 1、ADC配置 2、DMA配置 二、ADC DMA配置——HAL库 1、ADC配置 2、DMA配置 三、用户侧 1、DMA开关 &#xff08;1&#xff09;、标准库 &#xff08;2&#xff09;、HAL库 2、DMA乒乓 &#xff08;1&#xff09;、标准库 &#xff…...

【0376】Postgres内核 分配 last safe MultiXactId

上一篇: 【0375】Postgres内核 XLOG 之 设置下一个待分配 MultiXactId 和 offset 文章目录 1. 最后一个安全的 MultiXactId1.1 计算 multi wrap limit1.2 计算 multi stop limit1.3 计算 multi warn limit1.4 计算 multi vacuum limit2. 初始化 MultiXactState 成员3. 完成 mu…...

php时间strtotime函数引发的问题 时间判断出错

在 PHP 中&#xff0c;strtotime 函数能处理的最大时间范围取决于您的系统和 PHP 版本。 一般来说&#xff0c;它可以处理的时间范围从 1901 年 12 月 13 日到 2038 年 1 月 19 日。超过这个范围可能会导致不可预测的结果或错误。 如果您需要处理更大范围的时间&#xff0c;可能…...

Kibana:LINUX_X86_64 和 DEB_X86_64两种可选下载方式的区别

最近需要在vm&#xff08;操作系统是 Ubuntu 22.04.4 LTS&#xff0c;代号 Jammy。这是一个基于 x86_64 架构的 Linux 发行版&#xff09;上安装一个7.17.8版本的Kibana&#xff0c;并且不采用docker方式。 在下载的时候发现有以下两个选项&#xff0c;分别是 LINUX_X86_64 和 …...

【LeetCode每日一题】 LeetCode 151.反转字符串中的单词

LeetCode 151.反转字符串中的单词 题目描述 给你一个字符串 s &#xff0c;请你反转字符串中单词的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意&#xff1a;…...

gitlab克隆仓库报错fatal: unable to access ‘仓库地址xxxxxxxx‘

首次克隆仓库&#xff0c;失效了&#xff0c;上网查方法&#xff0c;都说是网络代理的问题&#xff0c;各种清理网络代理后都无效&#xff0c;去问同事&#xff1a; 先前都是直接复制的网页url当做远端url&#xff0c;或者点击按钮‘使用http克隆’ 这次对于我来说有效的远端u…...

在已有vue cli项目中添加单元测试配置

使用的是vue cli ^4.0.0的脚手架&#xff0c;项目采用的vue2进行编写&#xff0c;项目本身是没有使用单元测试的。应该挺多项目还是使用的vue2的项目进行开发的&#xff0c;自己在开发中过程中&#xff0c;还是发生了挺多需要记录原来功能的情况&#xff0c;这个时候去翻文档明…...

企业级NoSql数据库REDIS集群

1.1数据库主要分为两大类:关系型数据库与 NoSQL数据库 关系型数据库&#xff0c;是建立在关系模型基础上的数把库&#xff0c;其借助于集合代数等数学概念和方法来处理数据库中的数掘主流的 MySQLOracle、Ms sOLSerer和 DB2 都属于这类传统数据库 NoSQL数据库&#xff0c;全称…...

HTML与数据抓取:GET与POST方法详解

讲GET和POST就不能只讲GET和POST 你要讲HTTP请求的基本概念&#xff1a; HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是互联网上应用最为广泛的一种网络协议&#xff0c;主要用于Web浏览器与Web服务器之间的数据通信。HTTP是一个基于…...

【es6复习笔记】模板字符串(3)

介绍 模板字符串是 ES6 引入的一种新的字符串声明方式&#xff0c;它使用反引号&#xff08;&#xff09;来定义字符串&#xff0c;而不是单引号&#xff08;&#xff09;或双引号&#xff08;"&#xff09;。模板字符串可以包含变量、表达式和换行符&#xff0c;这使得它…...

cursor保存更改操作技巧

1. 当我们在agent模式时&#xff0c;要求cursor更改代码时&#xff0c;cursor回答后&#xff0c;就已经更改了代码了&#xff0c;这时候就可以对程序进行编译和测试&#xff0c; 不一定先要点” accept“, 先测试如果没有问题再点“accept”&#xff0c;这样composer就会多一条…...

ASP.NET |日常开发中定时任务详解

ASP.NET &#xff5c;日常开发中定时任务详解 前言一、定时任务的概念与用途1.1 定义1.2 应用场景 二、在ASP.NET中实现定时任务的方式2.1 使用System.Timers.Timer2.2 使用Quartz.NET 三、定时任务的部署与管理3.1 部署考虑因素3.2 管理与监控 结束语优质源码分享 ASP.NET &am…...

【零基础保姆级教程】制作自己的数据集(二)——Labelme的安装与使用及常见的报错解决方法

前段时间安装了Labelimg&#xff0c;网上有些博客写着Labelme能进行语义分割的标注&#xff0c;但UI窗口就那么大找不着选项&#xff0c;只能打矩形框&#xff0c;为了能够标注自己的分割数据集&#xff0c;遂写下该教程以供参考。 采用Labelimg进行目标检测标注的教程如下。 …...

Move AI技术浅析(二):输入与预处理

一、视频输入模块 1.1 视频输入步骤详解 视频输入模块的主要任务是接收视频数据&#xff0c;并将其转换为后续处理所需的格式。具体步骤&#xff1a; 1.1.1 视频读取 步骤&#xff1a;从文件系统、网络流或摄像头读取视频数据。技术&#xff1a;使用 OpenCV 的 cv2.VideoCa…...

实践KDTS-WEB从mysql迁移到kingbasev9

数据库国产化替代数据迁移是一个复杂且关键的过程。这涉及到将原有数据库中的数据准确、完整地迁移到新的国产数据库中&#xff0c;同时确保数据的完整性和一致性。人大金仓提供了强大的数据库迁移工具&#xff08;KDTS&#xff09;对同构、异构数据库数据迁移&#xff1b; 数…...

WebGIS实战开源项目:智慧机场三维可视化(学习笔记)

From&#xff1a;新中地 1.简介 智慧机场解决方案&#xff0c;基于数字化大平台&#xff0c;融合AI、大数据、IoT、视频云、云计算等技术&#xff0c;围绕机场“运控、安防、服务”三大业务领域&#xff0c;构建“出行一张脸”及“运行一张图”两大场景化解决方案。 https://…...

2025年PMP项目管理考试时间一览表

PMP认证是全球项目管理领域公认的权威认证&#xff0c;它不仅能证明你在项目管理方面的专业水平&#xff0c;还能大大提升你的职场竞争力&#xff01; 随着企业对项目管理人才的需求不断增长&#xff0c;获得PMP认证将为你带来更多的职业机会和高薪职位。 为了帮助大家合理安排…...

20241224在ubuntu20.04.6下的终端分屏软件terminator的安装以及使用

20241224在ubuntu20.04.6下的终端分屏软件terminator的安装以及使用 2024/12/24 18:35 百度&#xff1a;终端分屏软件 https://blog.csdn.net/weixin_49693003/article/details/143683326 可以实现终端分屏的工具&#xff1a;terminator 安装&#xff1a; sudo apt-get insta…...

打造高效租赁小程序让交易更便捷

内容概要 在如今节奏飞快的商业世界里&#xff0c;租赁小程序如同一只聪明的小狐狸&#xff0c;迅速突围而出&#xff0c;成为商家与消费者之间的桥梁。它不仅简化了交易流程&#xff0c;还在某种程度上将传统租赁模式带入了互联网时代。越来越多的企业意识到&#xff0c;这种…...

光谱相机在农业中的具体应用案例

作物生长监测与产量预测 美国爱荷华州玉米种植园&#xff1a;农场主使用无人机搭载高光谱相机&#xff0c;定期对玉米田进行拍摄。通过分析光谱数据&#xff0c;获取玉米的叶面积指数、叶绿素含量等生长参数。在玉米生长关键期&#xff0c;依据这些参数及时调整施肥和灌溉方案…...

Linux RTC 驱动框架

目录 一、实时时钟&#xff08;RTC&#xff09;介绍1.1 概述1.2 功能1.3 应用场景1.4 工作原理1.5 对外接口1.6 常见 RTC 芯片1.7 在 Linux 系统中的应用1.8 注意事项 二、Linux 内核 RTC 驱动框架2.1 相关源码文件介绍2.2 核心数据结构2.2.1 struct rtc_device2.2.2 rtc_class…...

msyql数据库读写分离搭建

一.mysql读写分离:缓解主服务器的压力1.概念:主服务器写数据,从服务器读数据2.实现方法:客户端分离: 开发手动分离地址服务端分离: 数据库与应用之间加一个中间件,分离读写请求mysql-proxy,mysql-route,maxscaleamoeba,cobar,mycat2atlas,kingshard,vitees3.mycat配置方法:冷配…...

WWW23-多行为级联|级联图卷积网络的多行为推荐

论文&#xff1a;https://arxiv.org/abs/2303.15720 代码&#xff1a;https://github.com/SS-00-SS/MBCGCN 这篇论文MB-CGCN和上一篇CRGCN是同一个团队的&#xff0c;都是级联的方式。一个用了残差&#xff0c;一个用了特征转换&#xff0c;文章最后有discussion讨论了两者的不…...

【EthIf-14】EthIfGeneral容器配置-02

1.实际EthIfGeneral的配置实例 关闭DET接口开启发送确认中断开启接收中断主周期接收timeout主周期 2. 代码实例参考 阅读此部分代码,搞清楚代码分为几个section,大概瞄一眼就好,不用深究其含义,只需有一个宏观的层次结构的映像即可。 //Appl/GenData/EthIf_Cfg.h #...

近实时”(NRT)搜索、倒排索引

近实时&#xff08;Near Real-Time, NRT&#xff09;搜索 近实时&#xff08;NRT&#xff09;搜索是 Elasticsearch 的核心特性之一&#xff0c;指的是数据在被写入到系统后&#xff0c;可以几乎立即被搜索和查询到。虽然它不像传统数据库那样完全实时&#xff0c;但它的延迟通…...

Ubuntu20.04安装openMVS<成功>.colmap<成功>和openMVG<失败(已成功)>

一、安装openMVS 参考官方文档 sudo apt-get -y install git mercurial cmake libpng-dev libjpeg-dev libtiff-dev libglu1-mesa-dev eigen git clone https://gitlab.com/libeigen/eigen --branch 3.4 mkdir eigen_build cd eigen_build &&\cmake . ../eigen -…...

从测试服务器手动热部署到生产环境的实现

为了实现从测试服务器&#xff08;192.168.0.255&#xff09;手动热部署到生产环境&#xff08;172.168.20.100&#xff09;&#xff0c;可以采用多种方法。以下是详细的步骤和最佳实践&#xff0c;帮助你实现这一目标。 1. 准备生产环境 确保生产环境上的 Docker 和 Docker …...