【进阶篇】二、实现Java Agent的静态加载和动态加载

文章目录

  • 1、Java Agent
  • 2、两种加载模式
    • 静态加载模式
    • 动态加载模式
  • 3、静态加载模式实现
  • 4、动态加载的实现

1、Java Agent

通过Java Agent,生成一种特殊的jar包(一种工具),业务程序可以主动去调用jar包里的方法。比如下面这个有打印内存情况功能的agent:

在这里插入图片描述

2、两种加载模式

让Java程序执行Java Agent程序中的代码,实现方式:

静态加载模式

在Java程序开始执行前,先执行Agent的代码。在Java Agent的项目中编写一个premain的方法,并打包成jar包:

//premain,即在用户的main方法执行之前
public static void premain(string agentArgs, Instrumentation inst)

如果自己的程序是test.jar,可执行:

java -javaagent:./agent.jar -jar test.jar

如此,JVM将会加载agent中的代码去执行。premain方法会在主线程中执行:

在这里插入图片描述

动态加载模式

连接用户的Java进程,随时让Java Agent的代码执行,适用于Arthas类似的诊断工具。实现动态加载模式,需要在Java Agent项目中编写一个agentmain方法,并打成jar包:

public static void agentmain(string agentArgs, Instrumentation inst)

以下代码可以让Java Agent的代码在指定的Java进程中执行:

//动态连接到24200进程ID的java程序
VirtualMachine vm = VirtualMachine.attach("24200");

//加载java agent的jar并执行
vm.loadAgent("itheima-jvm-java-agent-jar-with-dependencies.jar");

如此,Java Agent的jar就会被执行。和静态加载的permain不同,agentmain方法的执行是在一个单独的线程里:

在这里插入图片描述

一点想法:感觉AOP和Java Agent的区别就是:前者是开发者在自己的程序里写的,且增强的时机更灵活。后者则独立于开发者自己的程序,能适用于所有的Java程序。

3、静态加载模式实现

  • 创建Java Agent的maven项目,添加maven-assembly-plugin插件,以便打出java agent的jar包
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <!--将所有的依赖都打入同一个jar包中,配置了这个,以后打的Agent包,既有我写的Agent代码,也有上面引入的依赖的代码-->
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <!--指定java agent相关的配置文件-->
                <archive>
                    <manifestFile>src/main/resources/MANIFEST.MF</manifestFile>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

  • 定义个类,写premain方法,写代理要执行逻辑
public class AgentMain {

    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("premain方法执行了...");
    }

}
  • 编写MANIFEST.MF文件,写Java Agent的属性
Manifest-Version: 1.0
Premain-Class: com.llg.AgentMain
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Can-Set-Native-Method-Prefix: true
  • 使用maven-assembly-plugin进行打包

在这里插入图片描述

  • 让另一个普通的Java程序,-javaagent启动,静态代理成功:

在这里插入图片描述

4、动态加载的实现

  • 创建Java Agent的maven项目,添加maven-assembly-plugin插件,以便打出java agent的ja(同上)
  • 定义个类,写agentmain方法,写代理要执行逻辑
public class AgentMain {

    public static void agentmain(String agentArgs,Instrumentation inst){
        System.out.println("agentmain执行了...");
    }

}
  • 编写MANIFEST.MF文件,写Java Agent的属性
Manifest-Version: 1.0
Agent-Class: com.llg.AgentMain
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Can-Set-Native-Method-Prefix: true
  • 使用maven-assembly-plugin进行打包(同上)
  • 启动普通的Java程序
  • 写个main方法,动态连接到运行中的java程序并加载执行Java Agent的Jar,实现动态代理(以后这个main方法就可以写在工具里,让用户只输入一个自己Java进程的PID,帮用户把传入到这个main,动态代理)
public class Test {
    public static void main(String[] args) throws  Exception {
    	//传入用户Java进程的PID,实现连接
        VirtualMachine vm = VirtualMachine.attach("45627");
        //执行Java Agent的里的agentmain方法
        vm.loadAgent("D:\\jmh2\\llg-agent\\target\\llg-agent-1.0-SNAPSHOT-jar-with-dependencies.jar");

    }
}
  • 效果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/537645.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++设计模式|创建型 1.单例模式

1.什么是单例模式&#xff1f; 单例模式的的核⼼思想在创建类对象的时候保证⼀个类只有⼀个实例&#xff0c;并提供⼀个全局访问点来访问这个实例。 只有⼀个实例的意思是&#xff0c;在整个应⽤程序中&#xff0c;只存在该类的⼀个实例对象&#xff0c;⽽不是创建多个相同类…

WPS二次开发系列:Gradle版本、AGP插件与Java版本的对应关系

背景 最近有体验SDK的同学反馈接入SDK出现报错&#xff0c;最终定位到原因为接入的宿主app项目的gradle版本过低导致&#xff0c;SDK兼容支持了android11的特性&#xff0c;需要对应的gradle插件为支持android11的版本。 现象 解决方案 将gradle版本升级至支持android11的插件版…

openGauss_5.0.1 企业版安装及问题记录(CentOS系统):主备模式服务器安装

目录 &#x1f4da;第一章 官方地址&#x1f4d7;安装包下载地址&#x1f4d7;文档指南 &#x1f4da;第二章 安装&#x1f4d7;准备工作&#x1f4d7;开始安装&#x1f4d5;创建XML配置文件&#x1f4d5;初始化安装环境&#x1f4d5;执行安装&#x1f4d5;验证 &#x1f4da;第…

volta(轻松切换管理Node.js版本)

Node.js版本管理 Volta提供了一个简单直观的命令行界面&#xff0c;可以轻松地安装、卸载、更新和切换Node.js版本。 Volta 既可以全局使用&#xff0c;也可以在项目级别使用&#xff0c;可以为每个项目单独设置node版本&#xff0c;nvm不行。 下载安装Volta 参考&#xff1a; …

vue3 依赖-组件tablepage-vue3说明文档,列表页快速开发,使用思路及范例(Ⅲ)列表项及分页器配置及props配置

vue3 依赖-组件tablepage-vue3说明文档&#xff0c;列表页快速开发&#xff0c;使用思路及范例&#xff08;Ⅰ&#xff09;配置项文档 vue3 依赖-组件tablepage-vue3说明文档&#xff0c;列表页快速开发&#xff0c;使用思路及范例&#xff08;Ⅱ&#xff09;搜索及数据获取配…

基于SpringBoot的冬奥会科普平台

基于SpringBoot的冬奥会科普平台系统设计与实现 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发…

pip install opencv-python出现ModuleNotFoundError: No module named ‘skbuild‘错误解决方案

问题描述 File “”, line 1, in File “/tmp/pip-build-o148qsmj/opencv-python/setup.py”, line 10, in from skbuild import cmaker, setup ModuleNotFoundError: No module named ‘skbuild’ Command “python setup.py egg_info” failed with error code 1 in /tmp…

Java入门-数组

数组 什么是数组 数组( array )是一种最简单的复合数据类型&#xff0c;它是有序数据的集合&#xff0c;数组中的每个元素具有相同的数据类型&#xff0c;可以用一个统一的数组名和不同的下标来确定数组中唯一的元素。 数组的内存结构是分配一系列内存大小相等的连续空间。 …

Vue 引入config.js后别的js访问不到window对象下的属性

Vue项目里,我们项目配置的请求服务器地址都是在public里config.js里,如下例: 然后在index.html里引入config.js,如下图: 这里要注意的是,script的src要写上<%= BASE_URL %>,代码如下: <!DOCTYPE html> <html><head><meta charset="…

SNRO 编号范围对象管控,唯一ID

事务代码:SNRO 代码引用: DATA: MAXTID TYPE I,NEWNO TYPE CHAR8. CALL FUNCTION NUMBER_RANGE_ENQUEUE EXPORTING OBJECT ZQC57 EXCEPTIONS FOREIGN_LOCK 1 OBJECT_NOT_FOUND 2 SYSTEM_FAILURE 3 OTHERS …

Python3.7编程之病毒

基础篇 什么是病毒 病毒&#xff0c;指的是一些通过非法手段获取系统的一些权限&#xff0c;然后进行破坏或者盗取。 病毒分为两类&#xff1a; 1、破坏型 这类病毒往往会将系统弄的乱七八糟&#xff0c;比如把你的U盘删光&#xff0c;把你的系统背景调成黑客图片&#xff0c…

NoETL 公开课预告|下周二,第三代指标平台即将展露真容

100% 统一指标口径、100% 自动化指标开发、100% 灵活指标分析、强大的指标定义能力和查询加速性能、“管、研、用”一体、做“轻”数仓…… 很多小伙伴都非常好奇 buff 叠满的第三代指标平台 Aloudata CAN 到底长什么样。接下来我们安排了 7 期开箱直播&#xff0c;结合企业业…

Flutter学习13 - Widget

1、Flutter中常用 Widget 2、StatelessWidget 和 StateFulWidget Flutter 中的 widget 有很多&#xff0c;但主要分两种&#xff1a; StatelessWidget无状态的 widget如果一个 widget 是最终的或不可变的&#xff0c;那么它就是无状态的StatefulWidget有状态的 widget如果一个…

腾讯云向量数据库-RAG介绍

1.说明 RAG结合LLM(通用大预言模型)构件基于私有文档、专业领域知识、实时信息的charbot。 2.RAG的主要步骤 知识切片成chunk向量化chunk入库query检索知识chunk构件prompts调用llm生成回答 3.优势 快速构件demo快速理解rag社区支持 4.痛点 投入大效果差调优难 5.RAG应…

MURF1640CT-ASEMI快恢复二极管MURF1640CT

编辑&#xff1a;ll MURF1640CT-ASEMI快恢复二极管MURF1640CT 型号&#xff1a;MURF1640CT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;16A 最大循环峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;4…

【Java】JDK1.8 HashMap源码,put源码详细讲解

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 在Java中&#xff0c;HashMap结构是被经常使用的&#xff0c;在面试当中也是经常会被问到的。这篇文章我给大家分享一下我对于HashMap结构源码的理解。 HashMap的存储与一般的数组不同&#xff0c;HashMap的每一个元素存…

SQLite从出生到现在(发布历史记录)(二十二)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;从 SQLite 3.5.9 迁移到 3.6.0&#xff08;二十一&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 引言&#xff1a; SQLite拥有别人无法比拟的装机量&#xff0c;究竟什么成就了SQLite呢&#xff0c;本…

WPS制作表格热图

最近看到一篇文献使用了表格热图&#xff0c;于是想着用wps制作一个类似的。表格热图可以使表格中的数字大小变得更加直观。 参考文献原文&#xff1a;Miller, O.L., Helman, D., Tal Svoray, Morin, E., Bonfil, D.J., 2019. Explicit wheat production model adjusted for s…

2024/4/2—力扣—栈的最小值

代码实现&#xff1a; typedef struct node {int val;struct node *next; } Node;typedef struct {struct node *top;int min; } MinStack;/** initialize your data structure here. */MinStack* minStackCreate() {MinStack *obj malloc(sizeof(*obj));obj->top NULL;ob…

Failure Unable to retrieve image details-解决Portainer与Docker v26不兼容问题

文章目录 前言解决过程解决方法一解决方法二 前言 今天登上服务器习惯性的升级了yum软件包&#xff0c;结果这一更新后导致Portainer不能正常使用&#xff0c;后续进行成功解决&#xff0c;简单记录一下 解决过程 事故过程模拟 当时顺手升级下docker版本(V26.0.1) 结果Porta…