This is the 26th day of my participation in Gwen Challenge

What is Java Agent (Probe)

Java agent, introduced in JDK1.5, is a technology that can modify Java bytecode on the fly. Java classes are compiled to form bytecodes that are executed by the JVM. The JVM obtains the bytecodes information before executing them and modifies them to accomplish some additional functions. This is Java Agent technology.

The principle of

The Java Agent can intercept and modify Java bytecodes before loading them. The Java Agent can modify loaded bytecodes while the JVM is running

Bytecode modification can be implemented at collection points of some framework or technology, application monitoring can be implemented, or additional operations can be added when executing specified methods or interfaces (printing logs, printing method execution times, collecting method inputs and results, etc.)

implementation

Java Agent implementation bytecode enhancement process is: 1. Modify bytecode 2. Load the new bytecode 3. Replace the old bytecode

The second step is to use a custom ClassLoader to load the modified bytecode, and the third step is to use the JVM to load or run the bytecode replacement, so the first step is to modify the bytecode how to do, at least most people do not modify the bytecode, so you need to use tools to modify.

Technical framework

  • JVMTI
  1. JVMTI is an abbreviation of JVM Tool Interface, which is a set of interfaces exposed by the JVM for user extension. JVMTI is event-driven, and the JVM will call some event callback interfaces when executing certain logic. These interfaces can be extended to users to implement their own logic
  • JVMTIAgent
  1. JVMTIAgent is a dynamic library that uses the interfaces exposed by JVMTI to implement user-generated logic (eclipse, IDEA and other tools code debugging is achieved through this)
  • JVMTIAgent has three main methods,
  1. Agent_OnLoad method, which is executed if the agent is loaded at startup

The Agent_OnAttach method, if the agent is not loaded at startup, we attach it to the target thread and then send load to the corresponding target process to load the agent. The Agent_OnAttach function is called during loading and the Agent_OnUnload method is called when the Agent unloads

  • instrument agent
  1. Instrument Agent implements the Agent_OnLoad method and Agent_OnAttach method, that is, the agent can be loaded at startup or dynamically loaded during runtime. The dynamically loaded agent depends on the ATTACH mechanism of the JVM. Run the load command to load the AGENT
  • The JVM Attach mechanism
  1. JVM attach allows one process to transfer commands to another process and perform internal operations, such as a thread dump, by executing jStack, and passing pid parameters to the thread that needs to dump. This is a Java Attach.
  • Class Transform implementation
  1. The first class load requires the scene to be transformed to issue a ClassFileLoad event when the class file is loaded, which is handed to the Instrument Agent to invoke ClassFileTransformer registered in the Java Agent to implement the bytecode modification
  • Implementation of Class Redefind
  1. Class redefinition, mainly for classes that have already been loaded

Java probe tool technology principle based on Java Agent and Java bytecode injection technology

In JDK5, the proxy class can only be set by specifying the JavaAgent parameter when the JVM is started using the command line parameter. In JDK6, the proxy class is not limited to setting the configuration parameter when the JVM is started. In JDK6, the Proxy class is set by attaching the Java Tool API. We can also easily set up dynamic loading proxy classes in the run process to achieve the purpose of instrumentation. The best use of Instrumentation is to define dynamic changes and operations for classes. The simplest example is to calculate the time required for a method to execute, without modifying the source code, using Instrumentation agents to implement this function, which, in a powerful way, is equivalent to doing AOP support at the JVM level, so that we can do AOP without modifying the application.