昨天整了半天没有整出来的那个结果最后是一个包名引用错了..
在MANIFEST.MF中使用的包名和我自己的包名没有对上…
首先搬运这个师傅关于java Instrument的原理
javaagent
在maven项目里面修改pom.xml文件然后添加入build的选项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <packaging>jar</packaging> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.2</version> <configuration> <archive> <manifestEntries> <Project-name>javaagent</Project-name> <Project-version>1.0</Project-version> <Premain-Class>com.javaagent.MyAgent</Premain-Class> <Can-Redefine-Classes>true</Can-Redefine-Classes> <Can-Retransform-Classes>true</Can-Retransform-Classes> </manifestEntries> </archive> <skip>true</skip> </configuration> </plugin>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build>
|
加入packing和build标签,
首先做一个MyAgent类,导入了java.lang.instrument.Instrumentation
的接口
这是一个Java1.6加进来的接口,作用就是你通过jvmti代理引用程序来jvm的访问(主要用于类的动态改变和操作),这里只是将其用于一个在main函数执行之前的劫持并加载我们自己的类。
1 2 3 4 5 6 7 8 9 10 11
| package com.javaagent;
import java.lang.instrument.Instrumentation;
public class MyAgent { public static void premain(String args, Instrumentation instrumentation) throws Exception { System.out.println("Hello javaagent permain:"+args); } }
|
上面这个premain方法就是Instrmentation中提供的一个方法,可以在main运行前先运行premain函数里面的内容。
接下来定义新一个新的类用来执行main函数
1 2 3 4 5 6 7
| public class MyAgentTest { public static void main(String[] args) { System.out.println("main"); } }
|
编辑一下MANIFEST.MF文件
在这个函数中需要定义好一个Premain-Class选项,这个用于定位刚刚写的MyAgent那个包含了Premain函数的类(就是包中类的位置),配置项填错就没法运行。
然后使用maven build这个package
最后配置vm options来添加一个javaagent在启动时添加参数
-javaagent:这里是之前package打包出来的jar包路径.jar=1
后面的参数1是premain函数接收的参数args。
最后运行这个MyAgentTest.java
使用ByteBuddy构建一个java Agent
只需要加依赖然后修改一下就好,添加两个依赖,和之前文章一样先导入ByteBuddy
1 2 3 4 5 6 7 8 9 10 11 12
| <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy</artifactId> <version>1.12.2</version> </dependency>
<dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy-agent</artifactId> <version>1.12.2</version> <scope>test</scope> </dependency>
|
重写premain
方法
官方教程给的使用ByteBuddy创建一个java Agent的方法
创建 Java Agents
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class ToStringAgent { public static void premain(String arguments, Instrumentation instrumentation) { new AgentBuilder.Default() .type(isAnnotatedWith(ToString.class)) .transform(new AgentBuilder.Transformer() { @Override public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, ClassLoader classloader) { return builder.method(named("toString")) .intercept(FixedValue.value("transformed")); } }).installOn(instrumentation); } }
|
然后根据这个形式去写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| package com.javaagent;
import net.bytebuddy.agent.builder.AgentBuilder; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.matcher.ElementMatchers; import net.bytebuddy.utility.JavaModule;
import java.lang.instrument.Instrumentation;
public class MyAgent { public static void premain(String args, Instrumentation instrumentation) throws Exception {
System.out.println("this is an perform monitor agent.");
AgentBuilder.Transformer transformer = new AgentBuilder.Transformer() { @Override public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) { return builder .method(ElementMatchers.<MethodDescription>any()) .intercept(MethodDelegation.to(TimeInterceptor.class)); }
};
AgentBuilder.Listener listener = new AgentBuilder.Listener() { @Override public void onDiscovery(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
}
@Override public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded, DynamicType dynamicType) {
}
@Override public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded) {
}
@Override public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) {
}
@Override public void onComplete(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
} };
new AgentBuilder .Default() .type(ElementMatchers.nameStartsWith("com.javaagent.MyAgentTest")) .transform(transformer) .with(listener) .installOn(instrumentation); }
}
|
实现委托
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.javaagent;
import net.bytebuddy.implementation.bind.annotation.Origin; import net.bytebuddy.implementation.bind.annotation.RuntimeType; import net.bytebuddy.implementation.bind.annotation.SuperCall;
import java.lang.reflect.Method; import java.util.concurrent.Callable;
public class TimeInterceptor { @RuntimeType public static Object intercept(@Origin Method method, @SuperCall Callable<?> callable) throws Exception { long start = System.currentTimeMillis(); try { return callable.call(); } finally { System.out.println(method + ": took " + (System.currentTimeMillis() - start) + "ms"); } } }
|
MyAgentTest
进行调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.javaagent;
public class MyAgentTest {
private void fun1() throws Exception { System.out.println("this is fun 1."); Thread.sleep(500); }
private void fun2() throws Exception { System.out.println("this is fun 2."); Thread.sleep(500); }
public static void main(String[] args) throws Exception { MyAgentTest test = new MyAgentTest(); test.fun1(); test.fun2();
} }
|
同样先build然后在进行运行
参考
http://www.jinyunlong.xyz/articles/2021/05/15/1621089190040.html
https://www.cnblogs.com/tr1ple/p/12709402.html
https://github.com/hawkingfoo/demo-agent
http://rui0.cn/archives/1063
http://www.noobyard.com/article/p-smvzgpzs-dh.html