├── .gitignore
├── bytebuddy
├── dependency-reduced-pom.xml
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── cn
│ │ └── iocoder
│ │ └── learning
│ │ └── bytebuddy
│ │ ├── Agent.java
│ │ ├── Dog.java
│ │ ├── Example001.java
│ │ ├── Example002.java
│ │ ├── IAnimal.java
│ │ └── MyServiceInterceptor.java
│ └── resources
│ └── META-INF
│ └── MANIFEST.MF
├── example01
├── pom.xml
├── readme.md
└── src
│ └── main
│ └── java
│ └── cn
│ └── iocoder
│ └── learning
│ ├── Cat.java
│ ├── Dog.java
│ └── Main.java
├── javaagent01
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── cn
│ │ └── iocoder
│ │ └── learning
│ │ └── javaagent01
│ │ ├── Agent.java
│ │ └── ClassFileTransformerDemo.java
│ └── resources
│ └── META-INF
│ └── MANIFEST.MF
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 |
--------------------------------------------------------------------------------
/bytebuddy/dependency-reduced-pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | parent
5 | cn.iocoder.learning
6 | 1.0-SNAPSHOT
7 |
8 | 4.0.0
9 | bytebuddy
10 |
11 | agent
12 |
13 |
14 | maven-shade-plugin
15 | 2.4.1
16 |
17 |
18 | package
19 |
20 | shade
21 |
22 |
23 | false
24 | true
25 | true
26 | true
27 |
28 |
29 |
30 | cn.iocoder.learning.bytebuddy.Agent
31 |
32 |
33 |
34 |
35 |
36 | com.lmax:*
37 | org.apache.httpcomponents:*
38 | commons-logging:*
39 | commons-codec:*
40 | *:gson
41 | io.grpc:*
42 | io.netty:*
43 | com.google.*:*
44 | com.google.guava:guava
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | ${shade.package}.${shade.net.bytebuddy.source}
55 | org.skywalking.apm.dependencies
56 | UTF-8
57 | net.bytebuddy
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/bytebuddy/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | parent
7 | cn.iocoder.learning
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | bytebuddy
13 |
14 |
15 | org.skywalking.apm.dependencies
16 | UTF-8
17 | net.bytebuddy
18 | ${shade.package}.${shade.net.bytebuddy.source}
19 |
20 |
21 |
22 |
23 | net.bytebuddy
24 | byte-buddy
25 | 1.7.9
26 |
27 |
28 |
29 |
30 | agent
31 |
32 |
33 |
34 | org.apache.maven.plugins
35 | maven-shade-plugin
36 | 2.4.1
37 |
38 |
39 | package
40 |
41 | shade
42 |
43 |
44 | false
45 | true
46 | true
47 | true
48 |
49 |
51 |
52 | cn.iocoder.learning.bytebuddy.Agent
53 |
54 |
55 |
56 |
57 |
58 | com.lmax:*
59 | org.apache.httpcomponents:*
60 | commons-logging:*
61 | commons-codec:*
62 | *:gson
63 | io.grpc:*
64 | io.netty:*
65 | com.google.*:*
66 | com.google.guava:guava
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/bytebuddy/src/main/java/cn/iocoder/learning/bytebuddy/Agent.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning.bytebuddy;
2 |
3 | import net.bytebuddy.agent.builder.AgentBuilder;
4 | import net.bytebuddy.description.type.TypeDescription;
5 | import net.bytebuddy.dynamic.DynamicType;
6 | import net.bytebuddy.implementation.MethodDelegation;
7 | import net.bytebuddy.matcher.ElementMatchers;
8 | import net.bytebuddy.utility.JavaModule;
9 |
10 | import java.lang.instrument.Instrumentation;
11 |
12 | public class Agent {
13 |
14 | public static void premain(String agentArgs, Instrumentation instrumentation) {
15 |
16 | System.out.println("一点不萌");
17 |
18 | new AgentBuilder.Default()
19 | .type(ElementMatchers.any())
20 | .transform(new AgentBuilder.Transformer() {
21 | public DynamicType.Builder> transform(DynamicType.Builder> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule) {
22 | return builder
23 | // .method(ElementMatchers.any())
24 | .method(ElementMatchers.named("hello"))
25 | .intercept(MethodDelegation.to(MyServiceInterceptor.class))
26 | ;
27 | }
28 | })
29 | .with(new AgentBuilder.Listener() {
30 | public void onDiscovery(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
31 |
32 | }
33 |
34 | public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded, DynamicType dynamicType) {
35 | System.out.println("onTransformation :" + typeDescription);
36 | System.out.println("onTransformation :" + dynamicType);
37 | }
38 |
39 | public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded) {
40 |
41 | }
42 |
43 | public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) {
44 |
45 | }
46 |
47 | public void onComplete(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
48 |
49 | }
50 | })
51 | .installOn(instrumentation);
52 |
53 | System.out.println("有一点萌");
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/bytebuddy/src/main/java/cn/iocoder/learning/bytebuddy/Dog.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning.bytebuddy;
2 |
3 | public class Dog {
4 |
5 | public int hello() {
6 | return 0;
7 | }
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/bytebuddy/src/main/java/cn/iocoder/learning/bytebuddy/Example001.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning.bytebuddy;
2 |
3 | import net.bytebuddy.ByteBuddy;
4 | import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
5 | import net.bytebuddy.implementation.FixedValue;
6 | import net.bytebuddy.matcher.ElementMatchers;
7 |
8 | public class Example001 {
9 |
10 | public static void main(String[] args) throws IllegalAccessException, InstantiationException {
11 | Class dynamicType = new ByteBuddy()
12 | .subclass(Object.class)
13 | .method(ElementMatchers.named("toString"))
14 |
15 | .intercept(FixedValue.value("Hello World!"))
16 | .make()
17 | .load(Example001.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
18 | .getLoaded();
19 | Object s = dynamicType.newInstance();
20 | System.out.println(s);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/bytebuddy/src/main/java/cn/iocoder/learning/bytebuddy/Example002.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning.bytebuddy;
2 |
3 | import net.bytebuddy.ByteBuddy;
4 | import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
5 | import net.bytebuddy.implementation.MethodDelegation;
6 | import net.bytebuddy.matcher.ElementMatchers;
7 |
8 | public class Example002 {
9 |
10 | public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException {
11 | Class dynamicType = new ByteBuddy()
12 | .subclass(Dog.class)
13 | .method(ElementMatchers.named("hello"))
14 | .intercept(MethodDelegation.to(MyServiceInterceptor.class))
15 | .make()
16 | .load(Example002.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
17 | .getLoaded();
18 |
19 | Object s = dynamicType.newInstance();
20 | System.out.println(((Dog)s).hello());
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/bytebuddy/src/main/java/cn/iocoder/learning/bytebuddy/IAnimal.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning.bytebuddy;
2 |
3 | public interface IAnimal {
4 | }
5 |
--------------------------------------------------------------------------------
/bytebuddy/src/main/java/cn/iocoder/learning/bytebuddy/MyServiceInterceptor.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning.bytebuddy;
2 |
3 | import net.bytebuddy.implementation.bind.annotation.RuntimeType;
4 | import net.bytebuddy.implementation.bind.annotation.SuperCall;
5 |
6 | import java.util.concurrent.Callable;
7 |
8 | public class MyServiceInterceptor {
9 |
10 | @RuntimeType
11 | public static Object intercept(@SuperCall Callable> zuper) throws Exception {
12 | System.out.println("intercept:拦截了");
13 |
14 | // return zuper.call();
15 | return 2;
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/bytebuddy/src/main/resources/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Premain-Class: cn.iocoder.learning.bytebuddy.Agent
3 | Can-Redefine-Classes: true
4 |
--------------------------------------------------------------------------------
/example01/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | parent
7 | cn.iocoder.learning
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | example01
13 |
14 |
15 |
--------------------------------------------------------------------------------
/example01/readme.md:
--------------------------------------------------------------------------------
1 | 简单的 JavaAgent 练手
--------------------------------------------------------------------------------
/example01/src/main/java/cn/iocoder/learning/Cat.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning;
2 |
3 | public class Cat {
4 |
5 | public int hello() {
6 | return 2;
7 | }
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/example01/src/main/java/cn/iocoder/learning/Dog.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning;
2 |
3 | public class Dog {
4 |
5 | public int hello() {
6 | return 0;
7 | }
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/example01/src/main/java/cn/iocoder/learning/Main.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning;
2 |
3 | public class Main {
4 |
5 | public static void main(String[] args) {
6 | System.out.println("夜太黑");
7 |
8 | System.out.println(new Dog().hello());
9 | }
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/javaagent01/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | parent
7 | cn.iocoder.learning
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 | jar
12 |
13 | java-agent-01
14 |
15 |
16 | agent
17 |
18 |
19 |
20 | org.apache.maven.plugins
21 | maven-jar-plugin
22 | 2.3.1
23 |
24 |
25 | src/main/resources/META-INF/MANIFEST.MF
26 |
27 |
28 |
29 |
30 |
31 | maven-assembly-plugin
32 |
33 | ${basedir}
34 |
35 | true
36 |
37 | true
38 |
39 |
40 | cn.iocoder.learning.javaagent01.Agent
41 |
42 |
43 |
44 | jar-with-dependencies
45 |
46 |
47 |
48 |
49 | org.apache.maven.plugins
50 | maven-compiler-plugin
51 |
52 | 1.7
53 | 1.7
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/javaagent01/src/main/java/cn/iocoder/learning/javaagent01/Agent.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning.javaagent01;
2 |
3 | import java.lang.instrument.Instrumentation;
4 |
5 | public class Agent {
6 |
7 | // public static void premain(String agentArgs) {
8 | // System.out.println("我是一个萌萌哒的 Java Agent");
9 | // try {
10 | // Thread.sleep(2000L);
11 | // } catch (InterruptedException e) {
12 | // e.printStackTrace();
13 | // }
14 | // }
15 |
16 | public static void premain(String agentArgs, Instrumentation instrumentation) {
17 |
18 | instrumentation.addTransformer(new ClassFileTransformerDemo());
19 |
20 | System.out.println("一点不萌");
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/javaagent01/src/main/java/cn/iocoder/learning/javaagent01/ClassFileTransformerDemo.java:
--------------------------------------------------------------------------------
1 | package cn.iocoder.learning.javaagent01;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.lang.instrument.ClassFileTransformer;
8 | import java.lang.instrument.IllegalClassFormatException;
9 | import java.security.ProtectionDomain;
10 |
11 | public class ClassFileTransformerDemo implements ClassFileTransformer {
12 |
13 | public byte[] transform(ClassLoader loader, String className, Class> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
14 | System.out.println("className: " + className);
15 | if (!className.equalsIgnoreCase("cn/iocoder/learning/Dog")) {
16 | return null;
17 | }
18 | // return getBytesFromFile("cn/iocoder/learning/Cat");
19 | return getBytesFromFile("/Users/yunai/Java/learning/example01/Dog.class");
20 | }
21 |
22 | public static byte[] getBytesFromFile(String fileName) {
23 | File file = new File(fileName);
24 | try (InputStream is = new FileInputStream(file)) {
25 | // precondition
26 |
27 | long length = file.length();
28 | byte[] bytes = new byte[(int) length];
29 |
30 | // Read in the bytes
31 | int offset = 0;
32 | int numRead = 0;
33 | while (offset = 0) {
35 | offset += numRead;
36 | }
37 |
38 | if (offset < bytes.length) {
39 | throw new IOException("Could not completely read file "
40 | + file.getName());
41 | }
42 | is.close();
43 | return bytes;
44 | } catch (Exception e) {
45 | System.out.println("error occurs in _ClassTransformer!"
46 | + e.getClass().getName());
47 | return null;
48 | }
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/javaagent01/src/main/resources/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Premain-Class: cn.iocoder.learning.javaagent01.Agent
3 | Can-Redefine-Classes: true
4 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | cn.iocoder.learning
8 | parent
9 | pom
10 | 1.0-SNAPSHOT
11 |
12 | javaagent01
13 | example01
14 | bytebuddy
15 |
16 |
17 |
--------------------------------------------------------------------------------