200316-IDEA + Maven Zero base Build Java Agent project

Java agents (Java probes) have been around since jdk1.5, but for most business development javaers, they are somewhat strange and unfamiliar; Although agent development is rarely involved in actual business development, every Java development has been used, such as using IDEA to write a helloworld.java, and run it, and look carefully at the console output

This article will be an introduction to Java Agent and will teach you how to develop a Java Agent with statistical method time

I. Java Agent development

First, clear our development environment, choose IDEA as the editor, Maven for package management

1. Core logic

Create a new project (or submodule), and then create a new SimpleAgent class

public class SimpleAgent {

    /** * JVM arguments start, run this method **@param agentArgs
     * @param inst
     */
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("premain");
    }

    /** * Dynamic attach mode to start, run this method **@param agentArgs
     * @param inst
     */
    public static void agentmain(String agentArgs, Instrumentation inst) {
        System.out.println("agentmain"); }}Copy the code

Let’s ignore the specific gameplay of the two methods above and briefly review the differences between the two methods, as noted in the notes

  • JVM argument form: call the premain method
  • Attach: Call the AgentMain method

The JVM mode, that is, the target application that will use this agent, needs to specify the JVM parameter – JavaAgent :xxx.jar at startup. This mode can be used when the agent we provide is a basic required service

After the target application is started, no -JavaAgent is added to load our agent and we still want the target application to use our agent. At this time, we can use attach mode to use our agent (the specific use posture will be introduced later). It is natural to think that if our agent is used to debug and locate problems, it can be used in this way

Pack 2.

SimpleAgent (SimpleAgent, SimpleAgent, SimpleAgent, SimpleAgent, SimpleAgent

The Maven plugin makes it relatively easy to export a compliant Java Agent package. There are two common uses

A. Pom Specifies the configuration

In the pem. XML file, add the following configuration. Note the parameters in the manifestEntries TAB

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifestEntries>
                        <Premain-Class>com.git.hui.agent.SimpleAgent</Premain-Class>
                        <Agent-Class>com.git.hui.agent.SimpleAgent</Agent-Class>
                        <Can-Redefine-Classes>true</Can-Redefine-Classes>
                        <Can-Retransform-Classes>true</Can-Retransform-Classes>
                    </manifestEntries>
                </archive>
            </configuration>

            <executions>
                <execution>
                    <goals>
                        <goal>attached</goal>
                    </goals>
                    <phase>package</phase>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Copy the code

In the target directory, you can see a jar package named jar-with-dependencies

B. Manifest. MF Configuration file

Perhaps more common through the manifest.mf configuration file, here is a brief introduction to using poses

  • Under Resources, create a new directoryMETA-INF
  • inMETA-INFCreate a file in the directoryMANIFEST.MF

The file contents are as follows

The Manifest - Version: 1.0 Premain - Class: com. Git. Hui. Agent. SimpleAgent agent - Class: com.git.hui.agent.SimpleAgent Can-Redefine-Classes:true
Can-Retransform-Classes: true

Copy the code

Note that the last blank line (if I didn’t show it above, it’s probably a markdown rendering problem) should not be missing. In idea, there will be an error warning when deleting the last line

Then our POM.xml configuration needs to be modified accordingly

<build>
  <plugins>
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-assembly-plugin</artifactId>
          <configuration>
              <descriptorRefs>
                  <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <archive>
                  <manifestFile>
                      src/main/resources/META-INF/MANIFEST.MF
                  </manifestFile>
                  <! --<manifestEntries>-->
                      <! --<Premain-Class>com.git.hui.agent.SimpleAgent</Premain-Class>-->
                      <! --<Agent-Class>com.git.hui.agent.SimpleAgent</Agent-Class>-->
                      <! --<Can-Redefine-Classes>true</Can-Redefine-Classes>-->
                      <! --<Can-Retransform-Classes>true</Can-Retransform-Classes>-->
                  <! --</manifestEntries>-->
              </archive>
          </configuration>

          <executions>
              <execution>
                  <goals>
                      <goal>attached</goal>
                  </goals>
                  <phase>package</phase>
              </execution>
          </executions>
      </plugin>
  </plugins>
</build>
Copy the code

Also packaged with the MVN assembly:assembly command

II. The Agent is used

Agent is available, the next step is to test the use of agent. The above two ways are proposed, and we will explain them separately below

1. The JVM parameter

Start by creating a new demo project and writing a simple test class

public class BaseMain {

    public int print(int i) {
        System.out.println("i: " + i);
        return i + 2;
    }

    public void run(a) {
        int i = 1;
        while (true) {
            i = print(i);
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) { e.printStackTrace(); }}}public static void main(String[] args) throws InterruptedException {
        BaseMain main = new BaseMain();
        main.run();
        Thread.sleep(1000 * 60 * 60); }}Copy the code

In the test class, there is an infinite loop, each 1s to call the print method, IDEA test, can be directly in the configuration class, add JVM parameters, as follows

Note that the content in the red box is the absolute address of the agent packaged in the previous section: -javaAgent :/Users/…. / target/Java agent – 1.0 – the SNAPSHOT – jar – with – dependencies. The jar

After executing the main method, you see console output

Notice that premain is the output of our SimpleAgent premain method, and it was output only once

2. Attach mode

When using attach mode, we can simply understand that we need to inject our agent into the target application, so we need to create a program to complete this task

public class AttachMain {
    public static void main(String[] args)
            throws IOException, AgentLoadException, AgentInitializationException, AttachNotSupportedException {
        // Attach method argument is the target application process number
        VirtualMachine vm = VirtualMachine.attach("36633");
        // Please replace this with your own agent absolute address
        vm.loadAgent("/Users/....... / target/Java agent - 1.0 - the SNAPSHOT - jar - with - dependencies. Jar"); }}Copy the code

The above logic is relatively simple. First, obtain the process number of the target application through JPS -L

When the above main method is executed, the console will output a log similar to the following two lines, which can be simply interpreted as connecting to the target application, losing an agent, and then waving the sleeve without taking any clouds away

Connected to the target VM, address: '127.0.0.1:63710', transport: 'socket'
Disconnected from the target VM, address: '127.0.0.1:63710', transport: 'socket'
Copy the code

Then look at the BaseMain output above, with a line of AgentMain sandwiched between them, to indicate that the Agent was successfully injected

3. Summary

This article introduces maven + IDEA environment, hand by hand to teach you to develop a Hello World version of JavaAgent and package the whole process

Two methods

methods instructions Use the pose
premain() Called when agent is loaded by JVM, that is, when the target application is started, agent is specified -javaagent:xxx.jar
agentmain() Agent is called when attach is running and used when the target application is working properly VirtualMachine.attach(pid)To specify the target process number

vm.loadAgent("... jar")Loading agent

Two packing positions

When packaging as a working Java Agent, you need to pay attention to the configuration parameters. There are two ways to do this: one is to specify the configuration directly in pom.xml

<manifestEntries>
    <Premain-Class>com.git.hui.agent.SimpleAgent</Premain-Class>
    <Agent-Class>com.git.hui.agent.SimpleAgent</Agent-Class>
    <Can-Redefine-Classes>true</Can-Redefine-Classes>
    <Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
Copy the code

The other is in the meta-INF/manifest.mf configuration file (note that the last blank line is indispensable).

The Manifest - Version: 1.0 Premain - Class: com. Git. Hui. Agent. SimpleAgent agent - Class: com.git.hui.agent.SimpleAgent Can-Redefine-Classes:true
Can-Retransform-Classes: true

Copy the code

After reading this article, I will find that the actual development of the Java Agent is not clear. Does the agent just print hello world in front of it? This is completely different from the imagined

The next blog post will teach you how to implement a method statistics time-consuming Java Agent package, will detail the use of Instrumentation interface to achieve bytecode modification, so as to achieve functional enhancements

II. The other

Source code 0.

  • Github.com/liuyueyi/ja…

1. A gray Blog:liuyueyi.github.io/hexblog

A gray personal blog, recording all the study and work in the blog, welcome everyone to go to stroll

2. Statement

As far as the letter is not as good, the above content is purely one’s opinion, due to the limited personal ability, it is inevitable that there are omissions and mistakes, if you find bugs or have better suggestions, welcome criticism and correction, don’t hesitate to appreciate

  • Micro Blog address: Small Gray Blog
  • QQ: a gray /3302797840

3. Scan attention

A gray blog