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

java 探针两种模式实战

分为两种
程序运行前的agent:premain
程序运行中的agent:agentmain
在程序运行前的agent

javaagent是java命令的一个参数,所以需要通过-javaagent 来指定一个jar包(就是我们要做的代理包)能够实现在主程序运行前来执行我们jar中的方法
1.pom文件中

<plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.5.1</version><!-- 指定maven编译的jdk版本。若不指定,maven3默认用jdk 1.5 maven2默认用jdk1.3 --><configuration><source>8</source><target>8</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.2.0</version><configuration><archive><!--自动添加META-INF/MANIFEST.MF --><manifest><addClasspath>true</addClasspath></manifest><manifestEntries><Menifest-Version>1.0</Menifest-Version><!-- <Agent-class>example.AgentMain</Agent-class> --><!-- 必须存在 --><Premain-Class>example.PreMainAgent</Premain-Class><Can-Redefine-Classes>true</Can-Redefine-Classes><Can-Retransform-Classes>true</Can-Retransform-Classes><!--                            <Manifest-Version>true</Manifest-Version>--><!--                            <Can-Set-Native-Method-Prefix>true</Can-Set-Native-Method-Prefix>--></manifestEntries></archive></configuration></plugin>
</plugins>

也可以使用META-INF/MANIFEST.MF文件
Manifest-Version: 1.0
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Premain-Class: com.example.PreMainAgent

注意:

  1. 最后需要多一行空行
  2. Can-Redefine-Classes :true表示能重定义此代理所需的类, 默认值为 false(可选)
  3. Can-Retransform-Classes :true 表示能重转换此代理所需的 类,默认值为 false (可选)
  4. Premain-Class :包含 premain 方法的类(类的全路径名)

程序运行前的agent:PreMainAgent 类

方法名称必须为premain
加载顺序为
premain(String agentArgs,Instrumentation inst)
若找不到则执行

premain(String agentArgs)
public class PreMainAgent {public static void premain(String agentArgs,Instrumentation inst) {System.out.println("agent参数:"+agentArgs);}
}

将此服务打成jar包
创建另一个简单的maven项目

public class Application {public static void main(String[] args) {System.out.println("main 运行 ");}
}

启动运行时增加
-javaagent:D:\agent-demo-1.0-SNAPSHOT.jar=option1=value1

运行结果
agent参数:k1=v1
main 运行

在程序运行中的agent:agentmain类

基础的maven项目

public class AgentMain {public static void agentmain(String agentArgs, Instrumentation inst) {inst.addTransformer(new DefineTransformer(),true);System.out.println("----------我是agentmain");System.out.println("----------agentArgs = " + agentArgs);}
}

addTransformer、getAllLoadedClasses,retransformClasses 方法
addTransformer
用于注册Transformer 可以通过编写ClassFileTransformer 接口的实现类来注册我们自己的转换器
类加载的时候会进入我们自己的Transformer中的transformer 函数进行拦截,此处如果不需拦截也可以不处理

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.Scanner;public class DefineTransformer implements ClassFileTransformer {public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {Scanner sc = new Scanner(System.in);System.out.println("Injected Class AgentMainDemo Successfully !");System.out.print("> ");try {InputStream is = Runtime.getRuntime().exec(sc.next()).getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is));String line;StringBuilder sb = new StringBuilder();while ((line = br.readLine()) != null){sb.append(line).append("\n");}System.out.println(sb);} catch (IOException e) {e.printStackTrace();}return classfileBuffer;}
}

getAllLoadedClasses
用于列出所有已加载的class ,可以通过遍历class数组来寻找我们需要重新定义的class

public static void agentmain(String agentArgs, Instrumentation inst) {inst.addTransformer(new DefineTransformer(),true);System.out.println("----------监控探针");Class[] allClass = inst.getAllLoadedClasses();for (Class c : allClass) {System.out.println(c.getName());}
}

retransformClasses
能对已加载的class进行重新定义,如果目标类已经被加载了,可以调用此函数重新触发这个拦截能够达到对已加载的类进行字节码修改的效果。

public static final String ClassName = "org.apache.catalina.core.ApplicationFilterChain";public static void agentmain(String agentArgs, Instrumentation inst) {inst.addTransformer(new DefineTransformer(), true);System.out.println("----------监控探针");Class[] allClass = inst.getAllLoadedClasses();for (Class c : allClass) {if (c.getName().equals(ClassName)) {try {System.out.println("Inject class exit :" + ClassName);//agentmain 是JVM运行时,需要调用 retransformClasses 重定义类 !!inst.retransformClasses(c);} catch (UnmodifiableClassException e) {throw new RuntimeException(e);}}}
}

在pom文件里添加

<plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.5.1</version><!-- 指定maven编译的jdk版本。若不指定,maven3默认用jdk 1.5 maven2默认用jdk1.3 --><configuration><source>8</source><target>8</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.2.0</version><configuration><archive><!--自动添加META-INF/MANIFEST.MF --><manifest><addClasspath>true</addClasspath></manifest><manifestEntries><Menifest-Version>1.0</Menifest-Version><Agent-class>example.AgentMain</Agent-class><!--                            <Premain-Class>example.PreMainAgent</Premain-Class>--><Can-Redefine-Classes>true</Can-Redefine-Classes><Can-Retransform-Classes>true</Can-Retransform-Classes><!--                            <Manifest-Version>true</Manifest-Version>--><!--                            <Can-Set-Native-Method-Prefix>true</Can-Set-Native-Method-Prefix>--></manifestEntries></archive></configuration></plugin>
</plugins>

打成jar包备用
在另一个项目中添加

import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;import java.util.List;public class AttachMain {public static void main(String[] args) throws Exception{// 生成jar包的绝对路径String path = "E:\\test-1.0-SNAPSHOT.jar";// 列出已加载的jvmList<VirtualMachineDescriptor> list = VirtualMachine.list();// 遍历已加载的jvmfor (VirtualMachineDescriptor v:list){// 打印jvm的 displayName 属性System.out.println(v.displayName());// 如果 displayName 为指定的类if (v.displayName().contains("AttachMain")){// 打印pidSystem.out.println("id >>> " + v.id());// 将 jvm 虚拟机的 pid 号传入 attach 来进行远程连接VirtualMachine vm = VirtualMachine.attach(v.id());// 将我们的 agent.jar 发送给虚拟机vm.loadAgent(path);// 解除链接vm.detach();}}}
}

注意,此处tools不会自动加载,需要pom文件里手动加载

<dependency><groupId>com.sun</groupId><artifactId>tools</artifactId><version>1.8</version><scope>system</scope><systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>

运行即可看到

说明已经成功

此时可以启动你的服务,然后修改displayname的判断条件,即可对系统服务是否运行进行监控

后面的服务相当于把上面的jar包挂载到你需要的服务上,可以触发jar包中的代码

相关文章:

java 探针两种模式实战

分为两种 程序运行前的agent&#xff1a;premain 程序运行中的agent&#xff1a;agentmain 在程序运行前的agent javaagent是java命令的一个参数&#xff0c;所以需要通过-javaagent 来指定一个jar包&#xff08;就是我们要做的代理包&#xff09;能够实现在主程序运行前来执行…...

uniGUI之MASK遮罩

在页面进行后台数据库操作的时候&#xff0c;不想 用户再进行 页面上的 其他操作&#xff0c;这时候就要 将页面 遮罩。例如UniDBGrid有LoadMask属性。 1]使用ScreenMask函数 2]JS调用 3]一个控件控制遮罩另一个控件(如Button遮罩UniDBGrid) //很简单&#xff0c;本例子就是告…...

DevOps云原生创建devops流水线(微服务项目上传git,打包镜像,部署k8s)

开发和运维人员的解决方案 一、中间件的部署&#xff08;Sentinel/MongoDB/MySQL&#xff09; 二、创建DevOps工程 邀请成员 三、创建流水线 四、编辑流水线 ①、拉取代码&#xff08;若失败&#xff0c;则将制定容器改为maven&#xff09; 若失败&#xff0c;则将命令改…...

【vim 学习系列文章 13.1 -- 自动命令autocmd 根据文件类型设置vim参数】

文章目录 autocmd 根据文件类型配置vim参数vim 文本类型 autocmd 根据文件类型配置vim参数 在 Vim 中&#xff0c;你可以使用 autocmd &#xff08;自动命令&#xff09;来根据文件类型自动执行特定的函数。首先&#xff0c;你需要定义这些函数&#xff0c;然后使用 autocmd 与…...

算法基础概念之数据结构

邻接表 每个点作为头节点接一条链表 链表中元素均为该头节点指向的点 优先队列 参数: ①储存元素类型 ②底层使用的存储结构(一般为vector) ③比较方式(默认小于)...

解决ES伪慢查询

一、问题现象 服务现象 服务接口的TP99性能降低 ES现象 YGC&#xff1a;耗时极其不正常, 峰值200次&#xff0c;耗时7sFULL GC&#xff1a;不正常,次数为1但是频繁&#xff0c;STW 5s慢查询&#xff1a;存在慢查询5 二 解决过程 1、去除干扰因素 从现象上看应用是由于某种…...

关于Ubuntu22.04恢复误删文件的记录

挂载在Ubuntu22.04下的固态盘有文件被误删了&#xff0c;该固态盘是ntfs格式的。 在网上找了很多教程&#xff0c;最后决定用TestDisk工具进行恢复。 现记录如下&#xff1a; Ubuntu安装testdisk sudo apt-get install testdisk运行testdisk sudo testdisk得到 我选择的是…...

Docker笔记:Docker Swarm, Consul, Gateway, Microservices 集群部署

关于 Consul 服务 Consul是Go语言写的开源的服务发现软件Consul具有服务发现、健康检查、 服务治理、微服务熔断处理等功能 Consul 部署方式1: 直接在linux 上面部署 consul 集群 1 &#xff09;下载 在各个服务器上 下载 consul 后解压并将其目录配置到环境变量中&#xff…...

浅析AI视频分析与视频管理系统EasyCVR平台及场景应用

人工智能的战略重要性导致对视频智能分析的需求不断增加。鉴于人工智能视觉技术的巨大潜力&#xff0c;人们的注意力正在从传统的视频监控转移到计算机视觉的监控过程自动化。 1、什么是视频分析&#xff1f; 视频分析或视频识别技术&#xff0c;是指从视频片段中提取有用信息…...

跨站点分布式多活存储建设方案概述

1-伴随着私有云、海量非结构数据的爆炸性增长&#xff0c;软件定义存储已经成为用户构建“敏捷IT” 架构的数据基石&#xff0c;同时越来越多的关键业务接入“敏捷IT” 架构。在分布式软件定义存储的产品架构下&#xff0c;怎样既保证对爆炸数据量的平稳承接&#xff0c;又能对…...

Github 2023-12-16开源项目日报Top10

根据Github Trendings的统计&#xff0c;今日(2023-12-16统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目2非开发语言项目2TypeScript项目1Jupyter Notebook项目1Go项目1PHP项目1JavaScript项目1C#项目1 精…...

c++ 中多线程的相关概念与多线程类的使用

1、多线程相关概念 1.1 并发、并行、串行 并发&#xff08;Concurrent&#xff09;&#xff1a;并发是指两个或多个事件在同一时间间隔内运行。在操作系统中&#xff0c;是指一个时间段中有几个程序都处于已启动运行到运行完毕之间&#xff0c;且这几个程序都是在同一个处理机…...

深入理解 hash 和 history:网页导航的基础(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…...

腾讯文档助力CRM集成:无代码连接电商与广告

腾讯文档API的简介与优势 腾讯文档API是一个强大的工具&#xff0c;它允许企业通过简单的无代码开发来实现与电商平台和客服系统的智能连接。这种连接不仅提高了工作效率&#xff0c;还优化了数据管理。使用腾讯文档智能表&#xff0c;商家可以享受多样的列类型、多维视图展示…...

学习使用echarts漏斗图的参数配置和应用场景

学习使用echarts漏斗图的参数配置和应用场景 前言什么是漏斗图漏斗图的特点及应用场景漏斗图的特点漏斗图常见的的应用场景&#xff1a; echarts中漏斗的常用属性echart漏斗代码美化漏斗图样式1、设置标题字体大小2、设置标签样式3、设置漏斗图为渐变颜色4、设置高亮效果5、设置…...

npm ,yarn 更换使用国内镜像源,阿里源,清华大学源

在平时开发当中&#xff0c;我们经常会使用 Npm&#xff0c;yarn 来构建 web 项目。但是npm默认的源的服务器是在国外的&#xff0c;如果没有梯子的话。会感觉特别特别慢&#xff0c;所以&#xff0c;使用国内的源是非常有必要的。 在这里插入图片描述 Nnpm&#xff0c; yarn …...

vue+react题集整理

1.Typescript中 interface 和 type 的差别是什么&#xff1f; interface只能用来描述对象类型 type可以描述任何类型组合 type后边需要有 interface后边没有 当多次使用相同名称定义一个 interface 时&#xff0c;它们会自动合并为一个接口。同名属性的不能进行类型覆盖修改&am…...

线程池ThreadPoolExecutor详解

线程池ThreadPoolExecutor详解 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们深入研究Java中线程池的强大工具——ThreadPoolExecutor&#xff0c;解析它的工作原理、配置参数…...

elasticsearch|大数据|kibana的安装(https+密码)

前言&#xff1a; kibana是比较好安装的&#xff0c;但https密码就比较麻烦一些了&#xff0c;下面将就如何安装一个可在生产使用的kibana做一个简单的讲述 一&#xff0c; kibana版本和下载地址 这里我想还是强调一下&#xff0c;kibana的版本需要和elasticsearch的版本一…...

vue javascript tree 层级数据处理

层级数据是有父子关系的数组&#xff0c;示例&#xff1a; const treeData [{id: 1b7e8e98cb1d4a1f81e4fe2dfd9a8458,name: 层级1,parentId: null,children: [{id: 0d45dd5bb4c14d64a3ab0b738add4b24,name: 层级1-1,parentId: 1b7e8e98cb1d4a1f81e4fe2dfd9a8458,children: [{…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...