├── .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 | --------------------------------------------------------------------------------