Java Agent (java probe) Although there is, but for the vast majority of business development javaer, this thing is quite magical and strange after jdk1.5; though in the actual business development, rarely involve the agent development, but each java developers have used, such as using the idea to write a HelloWorld.java, and run it, a closer look at the console output
This article deals as Beginners Java Agent, and taught you how to develop a statistical method time-consuming Java Agent
I. Java Agent Development
First clear our development environment, select IDEA as editor, maven for packet management
1. Core Logic
Create a new project (or sub-module), then we create a new class SimpleAgent
public class SimpleAgent {
/**
* jvm 参数形式启动,运行此方法
*
* @param agentArgs
* @param inst
*/
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("premain");
}
/**
* 动态 attach 方式启动,运行此方法
*
* @param agentArgs
* @param inst
*/
public static void agentmain(String agentArgs, Instrumentation inst) {
System.out.println("agentmain");
}
}
复制代码
Let's ignore the above two methods of specific play you a quick look at the difference between these two methods, the comments also say
- jvm parameters form: Call premain method
- attach ways: Call agentmain method
Which jvm way, that is to use the target application of this agent, at boot time, you need to specify jvm parameters -javaagent:xxx.jar
, when we provide agent belongs to the basic essential services can be used in this way
When the target application is started, and did not add -javaagent
load our agent, still want the target program using our agent, this time we can use attach ways to use (will be back on the use of specific postures), naturally think if our targeting agent to debug the problem, in this way can be
2. Package
Above a simple SimpleAgent put our core functionality of Agent finished (is that simple), you need to make a Jar package
By maven plugin, you can output a relatively simple compliance java agent package, there are two common use gestures
a. pom specified configuration
In the pom.xml file, add the following configuration, please note the manifestEntries
parameters within the tag
<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>
复制代码
Then by mvn assembly:assembly
command packaged in target
the directory, you can see a suffix jar-with-dependencies
jar package, that is our goal
b. MANIFEST.MF profile
Through the configuration file MANIFEST.MF
, may be more common, there is also a brief usage posture
- In the resource directory (Resources), the new directory
META-INF
- In the
META-INF
directory, create a new fileMANIFEST.MF
Document reads as follows
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
复制代码
Please note that the last of a blank line (if I do not show above it, mostly markdown render a problem), no less, in the idea, when you delete the last line, there have been mistakes remind
Then our pom.xml
configuration, we need to make the corresponding changes
<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>
复制代码
Also by mvn assembly:assembly
command packaging
II. Agent Use
With the agent, the next step is the need to test the use of use of the agent of the proposed two methods above are described separately below us
1. jvm parameters
First create a demo project, write a simple test class
public class BaseMain {
public int print(int i) {
System.out.println("i: " + i);
return i + 2;
}
public void run() {
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);
}
}
复制代码
Test class, there is an infinite loop, each 1s call about print method, when tested IDEA, you can directly configure the class, adding jvm parameters, as follows
Please note that the content is above the red box on a packed absolute address of agent: -javaagent:/Users/..../target/java-agent-1.0-SNAPSHOT-jar-with-dependencies.jar
After executing the main method, you will see the console output
Note that the above premain
, this is our top SimpleAgent
of the premain
methods output, and output only once
2. attach mode
When using the attach mode, you can simply want to be understood as our agent is injected into the target application, so we need to own up a program to do this thing
public class AttachMain {
public static void main(String[] args)
throws IOException, AgentLoadException, AgentInitializationException, AttachNotSupportedException {
// attach方法参数为目标应用程序的进程号
VirtualMachine vm = VirtualMachine.attach("36633");
// 请用你自己的agent绝对地址,替换这个
vm.loadAgent("/Users/......./target/java-agent-1.0-SNAPSHOT-jar-with-dependencies.jar");
}
}
复制代码
The above logic is relatively simple, first by jps -l
acquiring the target application's process ID
When finished above the main method, the Console log output two lines similar to the following, can be simply understood as I connect to the target application, and lost an agent, then a wisp of cloud do not take any leave the
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'
复制代码
Next, let's look at the output BaseMain above, sandwiched line agentmain
, to show that agent was successfully injected into it
3. Summary
This article describes the maven + environment under the idea, taught you how to develop a version JavaAgent hello world and the whole process of packing
Two methods
method | Explanation | Use gestures |
---|---|---|
premain() |
Called when jvm way to load the agent, that is the target application at startup, designated agent | -javaagent:xxx.jar |
agentmain() |
Call mode when running in attach agent, using the target application works | VirtualMachine.attach(pid) To specify the target process ID vm.loadAgent("...jar") loading agent |
Two kinds of packaged posture
When packaged as java agent available configuration parameters should be noted that, provided the above two methods, one is directly in the pom.xml
specified configuration
<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>
复制代码
Another configuration file is META-INF/MANIFEST.MF
written in (Note that the last blank line integral)
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
复制代码
Of course, after reading In this part, you will find the actual development of java agent is still not clear, do not output a line in front of the agent is hello world
to get away it, and imagine this is completely different ah
Next post will be taught you how to achieve a statistical time-consuming java agent package will be described in detail using the interface Instrumentation
to implement bytecode modification, in order to achieve enhanced
II. Other
0. Source
1. a gray Blog : liuyueyi.github.io/hexblog
A gray personal blog, recording all study and work in the blog, welcome to go around
2. Statement
Believe everything the book is not as good, above, is purely one of the words, due to limited personal capacity, it is inevitable omissions and mistakes, such as find a bug or have better suggestions are welcome criticism and generous gratitude
- Microblogging Address: little gray Blog
- QQ: a gray / 3302797840
3. Scan concern
A gray blog