• Java字节码


    Java Agent概述
    Java Agent是一种特殊类型的软件组件,它允许在Java虚拟机(JVM)运行时修改应用程序的字节码。这种技术通常用于性能监控、日志记录、系统调试等。Java Agent主要分为两类:

    1. 启动时加载的Agent(Pre-Main Agent)
    2. 运行时加载的Agent(Agent-On-Load)
    
    • 1
    • 2

    1. 启动时加载的Agent(Pre-Main Agent)
    这种类型的Agent在应用程序的主方法(main)执行之前加载。它们通常用于在应用程序启动时进行一些预处理,例如初始化日志框架、植入一些监控代码等。

    如何实现:

    在Agent代码中,你需要实现一个带有特定签名的premain方法。这个方法是由JVM在启动时自动调用的。
    premain方法的签名必须是:
    public static void premain(String agentArgs, Instrumentation inst)。
    agentArgs是传递给Agent的任何参数。
    inst是一个java.lang.instrument.Instrumentation实例,它提供了操作字节码的接口。
    代码示例:

    import java.lang.instrument.Instrumentation;
     
    public class MyAgent {
        public static void premain(String agentArgs, Instrumentation inst) {
            System.out.println("Executing premain.........");
            // 这里可以进行字节码操纵或其他初始化任务
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如何使用:

    将上述Agent编译成JAR文件,并在JAR的MANIFEST.MF文件中指定Premain-Class属性。
    使用-javaagent标志启动你的Java应用程序,指定Agent JAR文件。
    例如,在MANIFEST.MF中:

    Premain-Class: MyAgent
    
    • 1

    启动Java应用时的命令行:

    java -javaagent:path/to/agent.jar -jar myapp.jar
    
    • 1

    2. 运行时加载的Agent(Agent-On-Load)
    这种Agent可以在JVM运行时动态加载和附加,通常用于对正在运行的应用程序进行监控和修改。

    如何实现:

    在Agent代码中,你需要实现一个带有特定签名的agentmain方法。这个方法在Agent被动态加载到JVM时由JVM调用。
    agentmain方法的签名必须是:public static void agentmain(String agentArgs, Instrumentation inst)。
    代码示例:

    import java.lang.instrument.Instrumentation;
     
    public class MyRuntimeAgent {
        public static void agentmain(String agentArgs, Instrumentation inst) {
            System.out.println("Executing agentmain.........");
            // 这里可以进行字节码操纵或其他任务
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如何使用:

    编译Agent代码并打包成JAR文件,指定Agent-Class属性在MANIFEST.MF文件。
    使用特定的工具(如attach API)在运行时将Agent加载到目标JVM。
    在MANIFEST.MF中:

    Agent-Class: MyRuntimeAgent
    
    • 1

    动态加载Agent(使用attach API的示例):

    import com.sun.tools.attach.VirtualMachine;
     
    public class AttachExample {
        public static void main(String[] args) throws Exception {
            VirtualMachine vm = VirtualMachine.attach("targetJvmPid");
            vm.loadAgent("path/to/agent.jar", "optionalAgentArgs");
            vm.detach();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在上述代码中,targetJvmPid是你想要附加的JVM的进程ID。

    path/to/agent.jar : 这是Java Agent的JAR文件的路径。在实际使用中,你需要将其替换为实际的Agent JAR文件的路径。例如,如果你的Agent JAR文件名为myagent.jar并且位于当前目录下,那么这部分应该替换为myagent.jar。

    optionalAgentArgs:这是传递给Agent的可选参数。这个字符串将作为参数传递给Agent的agentmain方法。如果你的Agent不需要任何参数,这部分可以为空字符串或者完全省略。

    这些示例提供了如何实现和使用这两种类型的Java Agent的基本方法。实际应用中,你可能会根据需求在Agent中进行更复杂的操作,例如使用ASM或Javassist库进行字节码操作。

    两种实现方式:

    1、使用ASM进行字节码操作
    2、使用Javassist进行字节码操作
    
    • 1
    • 2
  • 相关阅读:
    YOLOv5从训练到移植
    关于electron中使用ffi-napi窗口遍历的过程及问题
    [nlp] RuntimeError: Llama is supposed to be a BPE model!报错解决
    一次线上故障:数据库连接池泄露后的思考
    Nginx实战
    第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京),签到题5题
    Set集合
    容器云多集群环境下如何实践 DevOps
    苹果电脑专业的条形码工具iBarcoder:助力高效条形码生成,提升工作效率
    「SpringCloud Alibaba」Sentinel实现熔断与限流
  • 原文地址:https://blog.csdn.net/u014365523/article/details/137279042