Download - No dark magic - Byte code engineering in the real world

Transcript
Page 1: No dark magic - Byte code engineering in the real world

JavaByte Code

EngineeringNo black magic

Torsten Curdt

Page 2: No dark magic - Byte code engineering in the real world

Virtual CPU

Java

Virtual Machine

Physical Machine

Page 3: No dark magic - Byte code engineering in the real world

.section __TEXT,__text,regular,pure_instructions .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 .machine ppc .cstring .align 2LC0: .ascii "Hello, world\0" .text .align 2 .globl _main_main: mflr r0 stmw r30,-8(r1) stw r0,8(r1) stwu r1,-80(r1) mr r30,r1 bcl 20,31,"L00000000001$pb""L00000000001$pb": mflr r31 stw r3,104(r30) addis r2,r31,ha16(LC0-"L00000000001$pb") la r3,lo16(LC0-"L00000000001$pb")(r2) bl L_printf$LDBLStub$stub li r0,0 mr r3,r0 lwz r1,0(r1) lwz r0,8(r1) mtlr r0 lmw r30,-8(r1) blr .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 .align 5L_printf$LDBLStub$stub: .indirect_symbol _printf$LDBLStub mflr r0 bcl 20,31,"L00000000001$spb""L00000000001$spb": mflr r11 addis r11,r11,ha16(L_printf$LDBLStub$lazy_ptr-"L00000000001$spb") mtlr r0 lwzu r12,lo16(L_printf$LDBLStub$lazy_ptr-"L00000000001$spb")(r11) mtctr r12 bctr .lazy_symbol_pointerL_printf$LDBLStub$lazy_ptr: .indirect_symbol _printf$LDBLStub .long dyld_stub_binding_helper .subsections_via_symbols

Native Assembler

#include <stdio.h>

int main(char** args) { printf("Hello, world"); return 0;}

gcc -S HelloWorld.c

Page 4: No dark magic - Byte code engineering in the real world

#include <stdio.h>

int main(char** args) { printf("Hello, world"); return 0;}

Native Assembler_main: mflr r0 stmw r30,-8(r1) stw r0,8(r1) stwu r1,-80(r1) mr r30,r1 bcl 20,31,"L00000000001$pb" ...

gcc -S HelloWorld.c

Page 5: No dark magic - Byte code engineering in the real world

Compiled from "HelloWorld.java"public class HelloWorld extends java.lang.Object{public HelloWorld(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return

public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, world! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return

}

Java Assembler

public class HelloWorld {

public static void main(String[] args) { System.out.println("Hello, world!"); }

}

javap -c HelloWorld

Page 6: No dark magic - Byte code engineering in the real world

public class HelloWorld {

public static void main(String[] args) { System.out.println("Hello, world!"); }

}

public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/ 3: ldc #3; //String Hello, world! 5: invokevirtual #4; //Method java/io/ 8: return}

Java Assembler

javap -c HelloWorld

Page 7: No dark magic - Byte code engineering in the real world

public class HelloWorld {

public static void main(String[] args) { System.out.println("Hello, world!"); }

}

.method public static main([Ljava/lang .limit stack 2 .limit locals 1 .line 4 getstatic java/lang/System/out Ljava/ ldc "Hello, world!" invokevirtual java/io/PrintStream/println .line 5 return.end method

Jasmin Syntax

Page 8: No dark magic - Byte code engineering in the real world

Tools

java -jar jasmin.jar HelloWorld.j

•Disassembler: Jasper

• Assembler: Jasmin

java -jar jasper.jar HelloWorld.class

Page 9: No dark magic - Byte code engineering in the real world

Roundtripjasmin

HelloWorld.j HelloWorld.class

jasper

Page 10: No dark magic - Byte code engineering in the real world

Libraries

•ASM (BSD-style)

•BCEL (ASL)

•CGLIB (ASL)

•Javassist (MPL/LGPL)

Page 11: No dark magic - Byte code engineering in the real world

Libraries

JavassistAOP

BCEL

ASM

CGLIB

Page 12: No dark magic - Byte code engineering in the real world

BCEL

•Object model based

•JDK 1.4 support

•Verifier

•“DOM”

Page 13: No dark magic - Byte code engineering in the real world

ASM

•Event driven

•DOM available

•JDK 1.6 support

•“SAX”

Page 14: No dark magic - Byte code engineering in the real world

BCEL vs ASM

•Community

•JDK support

•“DOM” vs “SAX”

•API

•Tool support

Page 15: No dark magic - Byte code engineering in the real world

BCEL vs ASM

•BCEL: xalan, findbugs, aspectj, javaflow, clirr, beanshell, just4log, ...

•ASM: jardiff, javaflow, groovy, cobertura, aspectwerkz, beanshell, retroweaver, ...

Page 16: No dark magic - Byte code engineering in the real world

demo

Page 17: No dark magic - Byte code engineering in the real world

Generation

Page 18: No dark magic - Byte code engineering in the real world

XSLTC

•XSLT to java compiler

•Creates a translet from xslt

•Translet as JAXP transformer

Page 19: No dark magic - Byte code engineering in the real world

XSLTC

XSLT Parser

SAX Parser XPath Parser

XSLT Compiler

BCEL class

na

tive

AP

I

JA

XP

/ T

rAX

AP

I

*.xsl

*.xml

Page 20: No dark magic - Byte code engineering in the real world

XSLTC Speed

gregor msxml jd.xslt xsltc saxon xalan-j

Page 21: No dark magic - Byte code engineering in the real world

Groovy

ASM ClassVisitor class

Groovy Parsergroovy

source

Page 22: No dark magic - Byte code engineering in the real world

Analysis

Page 23: No dark magic - Byte code engineering in the real world

Findbugs

•Static analysis for bug patterns

•False positives

Page 24: No dark magic - Byte code engineering in the real world

Findbugs

Page 25: No dark magic - Byte code engineering in the real world

Findbugs

Page 26: No dark magic - Byte code engineering in the real world

Clirr / Jardiff

•Diff for jars or class files

•Detecting API changes

Page 27: No dark magic - Byte code engineering in the real world

Jardiff

Page 28: No dark magic - Byte code engineering in the real world

Jardiff

Page 29: No dark magic - Byte code engineering in the real world

Dependency

•Analyses class dependencies

•Finding unused classes

•Renaming classes

http://vafer.org/projects/dependency

Page 30: No dark magic - Byte code engineering in the real world

Dependency

Set dependencies = DependencyUtils .getDependenciesOfClass( Class1.class );

Page 31: No dark magic - Byte code engineering in the real world

Dependency

new ResourceRenamer() { String getNewNameFor(String oldName) { if (oldName.startsWith( "java.util.HashMap")) { return "my." + oldName; } return oldName;}

Page 32: No dark magic - Byte code engineering in the real world

Modification

Page 33: No dark magic - Byte code engineering in the real world

Cobertura / Clover

•Testcase coverage

•Recording the execution path

•Maven plugin

Page 34: No dark magic - Byte code engineering in the real world

Cobertura

Page 35: No dark magic - Byte code engineering in the real world

Cobertura

Page 36: No dark magic - Byte code engineering in the real world

Throttling

•Wrap Socket to deliver throughput according to settings

•Cannot rewrite java.* classes

Page 37: No dark magic - Byte code engineering in the real world

Retroweaver

•Compile with jdk 1.5 features, run on 1.4

•Static conversion

•Runtime conversion

Page 38: No dark magic - Byte code engineering in the real world

Just4log

for(int i=0; i<500000; i++) { if(log.isDebugEnabled()) { log.debug("message" + someLongTaskToExecute()); } normalCodeToExecute();}

for(int i=0; i<500000; i++) { if(log.isDebugEnabled()) { log.debug("message" + someLongTaskToExecute()); } normalCodeToExecute();}

Page 39: No dark magic - Byte code engineering in the real world

AspectJ

public aspect LogAspect{ declare precedence : LogAspect, *;

pointcut voidCalls() : !within(LogAspect) && execution(void *.*(..)) );

Page 40: No dark magic - Byte code engineering in the real world

AspectJ

Object around() : voidCalls() {

Signature sig = thisJoinPoint.getSignature(); log.debug('<' + getFullSig(thisJoinPoint)); Object result = proceed(); log.debug('>' + sig.getName());

return result;

Page 41: No dark magic - Byte code engineering in the real world

Javaflow

class MyRunnable implements Runnable { public void run() { for(int i=0; i<10; i++ ) Continuation.suspend(); }}Continuation c = Continuation.startWith( new MyRunnable());Continuation d = Continuation.continueWith(c);...

Page 42: No dark magic - Byte code engineering in the real world

Javaflow

Page 43: No dark magic - Byte code engineering in the real world

What you can do

•reflection without j.l.reflection

•generate classes on the fly

•implement interface on the fly

Page 44: No dark magic - Byte code engineering in the real world

What you can do

•change visibility

•extend classes that are final

•modify vs forking

•...

Page 45: No dark magic - Byte code engineering in the real world

Thanks!