Upload
jyukutyo
View
914
Download
4
Embed Size (px)
Citation preview
Seasar2
/ Java (@jyukutyo)
#ccc_i61
#ccc_i31
( )@jyukutyo Java 2009 / 500SI 9 / 5blog : Fight the Future http://jyukutyo.hatenablog.comJJUG CCC2016 Spring2015 Spring
!!
#ccc_i612
#ccc_j33
#ccc_j34
JavaJava
Java#ccc_j35
(bytecode) https://ja.wikipedia.org/wiki/#ccc_j36
#ccc_j37
JavaScalaJRubyGroovy
Compiler
Classfile
cafe babe0000 00320017 0100JVMClassfileClassfileClassfileClassfileClassfile
(JIT)
Java#ccc_j38
#ccc_j39
#ccc_j310cafe babe 0000 0032 0017 0100 0a48 656c6c6f 576f 726c 6407 0001 0100 106a 6176612f 6c61 6e67 2f4f 626a 6563 7407 00030100 1048 656c 6c6f 576f 726c 642e 7363616c 6101 001e 4c73 6361 6c61 2f72 65666c65 6374 2f53 6361 6c61 5369 676e 61747572 653b 0100 0562 7974 6573 0100 ef060115 3a51 2101 0209 0215 0921 0253 336d593e 3c76 4e1d 3765 1505 1911 6102 1f665b42 2418 5050 0201 2109 3171 2144 01030d15 4121 0123 010a 0529 4155 0d1c 3770...(Emacshexl-find-file)
HelloWorld#ccc_j311
#ccc_j312
#ccc_j313
#ccc_j314
#ccc_j315cafe babe 0000 0032 0017 0100 0a48 656c6c6f 576f 726c 6407 0001 0100 106a 6176612f 6c61 6e67 2f4f 626a 6563 7407 00030100 1048 656c 6c6f 576f 726c 642e 7363616c 6101 001e 4c73 6361 6c61 2f72 65666c65 6374 2f53 6361 6c61 5369 676e 61747572 653b 0100 0562 7974 6573 0100 ef060115 3a51 2101 0209 0215 0921 0253 336d593e 3c76 4e1d 3765 1505 1911 6102 1f665b42 2418 5050 0201 2109 3171 2144 01030d15 4121 0123 010a 0529 4155 0d1c 3770...
1!#ccc_j316
#ccc_j317
Javassist Seasar2HibernateByteman JBossHibernatecglib SpringMockitoByte Buddy MockitoSpockObjectWeb ASM GuiceSpockBCEL #ccc_j318
#ccc_j319
javapjavapJavaJDK`javap -v []`#ccc_j320
javap -v HelloWorld#ccc_j321
#ccc_j322public class HelloWorld minor version: 0 major version: 52Constant pool: #1 = Methodref #6.#15 // java/lang/Object."":()V #2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #18 // Hello, world! #4 = Methodref #19.#20 // java/io/PrintStream.println:(Ljava/lang/String;)V...
#ccc_j323...public static voidmain(java.lang.String[]); Code: 0: getstatic #2 3: ldc #3 5: invokevirtual #4 8: return-- #0 = index of Constant pool...
#ccc_j324
#ccc_j325
Java AgentMavenGradleAnt#ccc_j326
Java Agent#ccc_j327
Java#ccc_j328
http://itpro.nikkeibp.co.jp/article/COLUMN/20061208/256374/
Java Agent#ccc_j329
#ccc_j330
#ccc_j331import java.lang.instrument.ClassFileTransformer;import java.lang.instrument.Instrumentation;
public class Agent { public static void premain(String agentArgs, Instrumentation inst) { inst.addTransformer(new ClassFileTransformer() { @Override public byte[] transform(ClassLoader loader,String className, Class classBeingRedefined, ProtectionDomain protectionDomain,byte[] classfileBuffer) throws IllegalClassFormatException { // } }); }}
premain()main()#ccc_j332
ClassFileTransformer#ccc_j333
Instrument API#ccc_j334
https://docs.oracle.com/javase/jp/7/api/java/lang/instrument/package-summary.html
Java Agent#ccc_j335
MANIFEST.MF#ccc_j336
MANIFEST.MFPremain-Classpremain()
#ccc_j337
MANIFEST.MFBoot-Class-Path JARJAR
#ccc_j338
#ccc_j339META-INF/MANIFEST.MF
Manifest-Version: 1.0Premain-Class: com.jyukutyo.AgentBoot-Class-Path: javassist-3.21.0-GA.jarCreated-By: Apache Maven 3.2.2Build-Jdk: 1.8.0_102
#ccc_j340
#ccc_j341public class Agent { public static void premain(String agentArgs, Instrumentation inst) { inst.addTransformer(new ClassFileTransformer() { @Override public byte[] transform(.., String className,..) { System.out.println(className); ... } }); }}
MANIFEST.MFJAR#ccc_j342
HelloWorld
java -javaagent:agent.jarexample.HelloWorld#ccc_j343
#ccc_j344java/lang/invoke/MethodHandleImpl...java/lang/invoke/MemberName$Factoryjava/lang/invoke/MethodHandleStaticsjava/lang/invoke/MethodHandleStatics$1sun/misc/PostVMInitHooksun/usagetracker/UsageTrackerClientjava/util/concurrent/atomic/AtomicBoolean...sun/launcher/LauncherHelperexample/HelloWorldsun/launcher/LauncherHelper$FXHelperjava/lang/Class$MethodArrayjava/lang/VoidHello World!...
(ClassFileTransformer)#ccc_j345
Javassist#ccc_j346
#ccc_j347
#ccc_j348public class Agent { public static void premain(...) { inst.addTransformer(new ClassFileTransformer() { public byte[] transform(..., byte[] classfile) { ... ClassPool cp = ClassPool.getDefault(); try { CtClass ct = cp.makeClass(new ByteArrayInputStream(classfile)); for (CtMethod cm: ct.getDeclaredMethods()) { cm.insertBefore("System.out.println($args); System.out.println($type);"); } return ct.toBytecode();
} catch (IOException | CannotCompileException e) { ...
HelloWorld
java -javaagent:agent.jarexample.HelloWorld#ccc_j349
#ccc_j350[Ljava.lang.Object;@754ba872voidHello World!
Javassist#ccc_j351
Javassit#ccc_j352
#ccc_j353 ClassPool cp = ClassPool.getDefault(); try { CtClass ct = cp.makeClass(new ByteArrayInputStream(classfile));CtClass
#ccc_j354 for (CtMethod cm: ct.getDeclaredMethods()) { cm.insertBefore("System.out.println($args); System.out.println($type);"); }CtClassCtMethodprintln()2
$#ccc_j355
$argsObject$typejava.lang.Class $classClass$_
https://jboss-javassist.github.io/javassist/tutorial/tutorial2.html
JavassitOSS#ccc_j356
Hibernate
#ccc_j357public synchronized byte[] enhance(String className, byte[] originalBytes) throws EnhancementException { try { final CtClass managedCtClass = classPool.makeClassIfNew( new ByteArrayInputStream(originalBytes)); if (enhance(managedCtClass)) { return getByteCode(managedCtClass); } else { return null; } } catch (IOException e) { log.unableToBuildEnhancementMetamodel(className); return null; }}org.hibernate.bytecode.enhance.internal.javassist.EnhancerImpl
#ccc_j358
JavaOSS#ccc_j359
JMockit
#ccc_j360public static void premain(String agentArgs, @Nonnull Instrumentation inst) throws IOException{ initialize(true, inst);}mockit.internal.startup.Startup
#ccc_j361
BytemancglibByte BuddyObjectWeb ASMBCEL#ccc_j362
(Javassit)#ccc_j363
BytemanRuleRule#ccc_j364
BytemanRule
#ccc_j365RULE hello worldCLASS com.jyukutyo.MainMETHOD mainAT ENTRYIF TRUE DO traceStack()ENDRULERule
#ccc_j366$ java -javaagent:byteman-3.0.6.jar=script:rule.btmcom.jyukutyo.Main(1)
Stack trace for thread maincom.jyukutyo.Main.main(Main.java:-1)Hello World!
Rule
Byte Buddy2015 Dukes Choice Award #ccc_j367
#ccc_j368public class Agent { public static void premain(String agentArgs, Instrumentation inst) { new AgentBuilder.Default() .type(ElementMatchers.any()) .transform(new AgentBuilder.Transformer() { @Override public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, ClassLoader classloader) { return builder.method( ElementMatchers.named("toString")) .intercept(FixedValue.value("transformed")); } }).installOn(inst); }}
toString()transform#ccc_j369
#ccc_j370$ java com.jyukutyo.Main
toString() is called.
$ java -javaagent:agent.jar com.jyukutyo.Main
transformed
()
#ccc_j371public class Agent { public static void premain(String agentArgs, Instrumentation inst) { new AgentBuilder.Default() .type(ElementMatchers.any()) .transform(new AgentBuilder.Transformer() { @Override public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, ClassLoader classloader) { return builder.method( ElementMatchers.named("toString")) .intercept(FixedValue.value("transformed")); } }).installOn(inst); }}
Web#ccc_j372
Attach API#ccc_j373
Attach APIJVMAPIcom.sun.tools.attachcom.sun.tools.attach.spiHotSpot VM#ccc_j374
Byte BuddyJavaAttach API#ccc_j375
Byte BuddyByteBuddyAgent#ccc_j376
#ccc_j377
Attach API#ccc_j378
#ccc_j379VirtualMachine vm = VirtualMachine.attach(9999");
vm.loadAgent(agent.jar");vm.detach();
pid
#ccc_j380
Attach API/tools.jar#ccc_j381
Spring Boot Web/testhello transformed #ccc_j382
SpringController
#ccc_j383@Controllerpublic class TestController {
@ResponseBody @RequestMapping(value = "test", method = RequestMethod.GET) public String index() { return "hello"; }}
#ccc_j384public static void agentmain(... inst) { ... String target = "com.jyukutyo.TestController; ByteBuddy byteBuddy = new ByteBuddy(); byteBuddy.redefine(TypePool.Default.of(classLoader) .describe(target).resolve(), ClassFileLocator.ForClassLoader.of(classLoader)) .method(ElementMatchers.named("index")) .intercept(FixedValue.value("transformed")) .make() .load(classLoader, ClassReloadingStrategy.of(inst));
new AgentBuilder.Default().with(byteBuddy) .installOn(inst);}
#ccc_j385public static void agentmain( String agentArgs, Instrumentation inst) throws Exception {VMpremain()agentmain()
#ccc_j386.method(ElementMatchers.named("index")).intercept(FixedValue.value("transformed"))
index()transformed
#ccc_j387MANIFEST.MF...Agent-Class: com.jyukutyo.AgentCan-Retransform-Classes: true
#ccc_j388mvn spring-boot:runhttp://localhost:8080/testjava -cp /Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/lib/tools.jar:. com.jyukutyo.Main [pid]http://localhost:8080/test
- Byte BuddyJava Attach API #ccc_j389
#ccc_j390
Q&A#ccc_j391