Giriş
Gnellikle şu şekilde kullanılır
AgentBuilder.Default() .type(...) .transform(...) .installOn(...)
Çalıştırılacak kod pre-main olarak düşünülür.
Örnek
Şöyle yaparız. Burada @Repeat olarak işaretli metod 3 kere çağrılıyor
public class Repeater { public static void premain(String arguments, Instrumentation instrumentation) { //1 var withRepeatAnnotation = isAnnotatedWith(named("ch.frankel.blog.instrumentation.Repeat")); //2 new AgentBuilder.Default() //3 .type(declaresMethod(withRepeatAnnotation)) //4 .transform((builder, typeDescription, classLoader, module, domain) -> builder //5 .method(withRepeatAnnotation) //6 .intercept( //7 SuperMethodCall.INSTANCE //8 .andThen(SuperMethodCall.INSTANCE) .andThen(SuperMethodCall.INSTANCE)) ).installOn(instrumentation); //3 } }Açıklaması şöyle
1. Required signature; it’s similar to the main method, with the added Instrumentation argument2. Match that is annotated with the @Repeat annotation. The DSL reads fluently even if you don't know it (I don't).3. Byte Buddy provides a builder to create the Java agent4. Match all types that declare a method with the @Repeat annotation5. Transform the class accordingly6. Transform methods annotated with @Repeat7. Replace the original implementation with the following8. Call the original implementation three times
Sonra şöyle yaparız. Burada bir fat jar oluşturuluyor
<plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifestEntries> <Premain-Class>ch.frankel.blog.instrumentation.Repeater</Premain-Class> </manifestEntries> </archive> </configuration> <executions> <execution> <goals> <goal>single</goal> </goals> <phase>package</phase> </execution> </executions> </plugin>ve şöyle yaparız
// create the agent mvn install // Run the app with the agent: java -javaagent:/~/.m2/repository/.../agent-1.0-SNAPSHOT-jar-with-dependencies.jar \ #1 -cp ./target/classes #2 ch.frankel.blog.instrumentation.Main
Örnek
Elimizde şöyle bir kod olsun. Bu instrumentation için kullanılacak kod. Bu koddaki premain metodu jvm'den önce çalışır. TimeFooter sınıfı Advice içindir. transform() metoduyla Advice metodlara takılır
Bu kodu agent olarak kullanılabilecek bir jar haline getirelimimport net.bytebuddy.agent.builder.AgentBuilder;import net.bytebuddy.asm.Advice;import net.bytebuddy.description.type.TypeDescription;import net.bytebuddy.dynamic.DynamicType;import net.bytebuddy.matcher.ElementMatchers;import net.bytebuddy.utility.JavaModule;import java.lang.instrument.Instrumentation;public class SimpleInstru {public static void premain(String argument,Instrumentation instrumentation) {System.out.println("Agent started at " + System.currentTimeMillis());Advice advice = Advice.to(TimeFooter.class);new AgentBuilder.Default().type(ElementMatchers.nameContains("ApplicationBeingTransformed")).transform((DynamicType.Builder<?> builder,TypeDescription type,ClassLoader loader,JavaModule module) -> {return builder.visit(advice.on(ElementMatchers.isMethod()));}).installOn(instrumentation);}public static class TimeFooter {@Advice.OnMethodExit(onThrowable = Throwable.class)public static void exit(@Advice.Origin String methodName) {System.out.println("Now exiting: \n"+methodName);}}}
javac -cp byte-buddy-1.10.22.jar;. SimpleInstru.java jar cfm simpleInstrumentation.jar instru.mf
SimpleInstru.class SimpleInstru\$TimeFooter.class
Premain-Class: SimpleInstru Class-Path: byte-buddy-1.10.22.jar
java -javaagent:simpleInstrumentation.jar -jar simpleApplication.jar
Hiç yorum yok:
Yorum Gönder