Presentation is loading. Please wait.

Presentation is loading. Please wait.

JavAssist X.class Class Loader My Loader X compile load JavAssist enables preload byte code modification.

Similar presentations

Presentation on theme: "JavAssist X.class Class Loader My Loader X compile load JavAssist enables preload byte code modification."— Presentation transcript:

1 JavAssist X.class Class Loader My Loader X compile load JavAssist enables preload byte code modification

2 What is Reflection? If a program can inspect itself while running, it’s said that the runtime system is reflective with respect to that program.

3 Levels of Reflection Introspection. –No alteration, read only. Behavioral Reflection. –Limited Alteration possible, such as method invocation. –In general : behavior of operations is changeable. Structural Reflection. –The ability to change data structures used by the runtime system, such as Class for example.

4 Java, AspectJ, and JavAssist Java provides Introspection: –getName. AspectJ provides Behavioral Reflection: –Aspects + Point cuts are used. –Compile time Weaving process integrates behavioral changes to precompiled base code. Javassist provides Structural Reflection: –Javassist API is in Java. –Customized runtime loader changes preloaded byte code.

5 How is Javassist implemented? CtClass c = new CtClass(“X.class”); //There’s nothing like Class X in the JVM so far! c.notFinal(); c.addField(…) c.addMethod(…) //c contains the altered byte code of X. c.load(); //Altered X is finally loaded into the JVM. cX.class X’ My Loader

6 Design Goals of Javassist 1.Source Level Abstraction. No knowledge of byte code is needed. API is purely in Java. 2.Efficient Structural Reflection. Reduce runtime overheads due to class reconstruction. 3.Safe Structural Reflection. Protect programmers from defected byte code composition.

7 Pursuing Javassist Design Goals. 1.Source Level Abstraction. Class rename. 2.Efficient Structural Reflection. Runtime compilation with addMethod. 3.Safe Structural Reflection. Class member removal.

8 The Javassist API Introspection Alteration. Adding a new Member. Altering a Method Body. Javassist Class Loader. Class{ Fields Constructors Methods } CtClass{ CtFields CtMethods }

9 CtClass Introspection

10 CtField & CtMethod Introspection

11 Alteration

12 Example: addMethod public class Xvector extends java.util.vector{ public void add(X e){ super.addElement(e); } CtMethod m = // method add() in XVector CtClass c = // class StringVector Classmap = new ClassMap(); map.put(“X”, ”java.lang.String”); c.addMethod(m, “addString”, map); Public void addString(java.lang.String e){ super.addElement(e); }

13 Example: setBody CtMethod m = // method which body is to be changed CodeConverter conv = new CodeConverter(); Conv.replaceNew(Xclass, Yclass, “create” ); m.instrument(conv); M( … ){ … Xclass xclass = new Xclass(3,4); … } M( … ){ … Yclass.create(3,4); … } Must be Static

14 Reflective Class Loader JavAssist default loader. User defined loader. Web Server. Off line.

15 Examples: Binary Code Adaptation. class X implements Writable{ public void write(PrintableStream s){..} } class X implements Printable{ public void (PrintableStream s){..} public void print(){write(System.out);} }

16 Examples: Binary Code Adaptation. class Exemplar implements Printable { public void write(PrintStream s) { /* dummy */ } public void print() { write(System.out); } } class Adaptor { //  THE JOB IS DONE HERE public void adapt(CtClass c) { CtMethod printM = /* method print() in Exemplar */; CtClass[] interfaces = c.getInterfaces(); for (int i = 0; i < interfaces.length; ++i) if (interfaces[i].getName().equals("Writable")) { interfaces[i] = CtClass.forName("Printable"); c.setInterfaces(interfaces); c.addMethod(printM, new ClassMap()); return; }

17 Behavioral Reflection. public class MyMetaObject extends MetaObject { public Object trapMethodCall(String methodName, Object[] args) { /* called if a method call is intercepted. */ } public Object trapFieldRead(String fieldName) { /* called if the value of a field is read. */ } public void trapFieldWrite(String fieldName, Object value) { /* called if a field is set. */ } }

18 Behavioral Reflection. public class C{ public int f; public int m(int x){ return x+f;} } public class C implements MetaLevel { public int m(int x) { /* notify a MetaObject. */ } public int f; private MetaObject _MetaObject = new MyMetaObject(this); public MetaObject _getMetaObject() { return _MetaObject; } public int orig_m(int x) { return x + f; } public static int read_f(Object target) {/* notify a MetaObject. */ } public static void write_f(Object target, int value) { /* notify a MetaObject. */ } }

19 Behavioral Reflection. class Exemplar { private MetaObject _MetaObject; public Object trap(Object[] args, String methodName) { return _MetaObject.trapMethodcall(methodName, args); } public static Object trapRead(Object[] args, String name) { Metalevel target = (Metalevel)args[0]; return target._getMetaObject().trapFieldRead(name); } public static Object trapWrite(Object[] args, String name) { Metalevel target = (Metalevel)args[0]; Object value = args[1]; target._getMetaObject().trapFieldWrite(name, value); }

20 Related Work: Reflection in Java. MetaXa and Kava enable behavioral reflection in Java, whereas JavAssist enable structural reflection. JavAssist can be used to achieve behavioral reflection, such as with MetaXa and Kava. Kirby’s system, allows a class definition at load time. It doesn’t support class redefining.

21 Related Work:Compile-Time MetaObject Protocol. Another architecture enabling structural reflection without modifying an existing runtime system is OpenJava. OpenJava was designed mainly for off-line use at compile time.

22 Related Work:Compile-Time MetaObject Protocol. OpenJava is source-code based. OpenJava alterations are on source code level. OpenJava involves a performance overhead due to source code manipulations. On the other hand it results with a fine- grained source code.

23 Related Work:Compile-Time MetaObject Protocol. JavAssist is bytecode based and doesn’t need source code( which is not always available). No performance overhead: the code is already compiled, therefore JavAssist achieves shorter loading time. JavAssist runs 10 times faster than OpenJava.

24 Related Work: Bytecode Translators. JOIE and JavaClass API provide functionality similar to JavAssist. Using them, the programmer is required to have a deep understanding of the Java byte code. JavAssist provides source-level abstraction for manipulating byte code in a safe manner.

25 Related Work: Others. OpenJIT: allows a Java program to control how byte code is compiled into native code. It provides better flexibility with method body redefinition, but doesn’t allow to add a new method or field to the class.

26 Conclusions. JavAssist is an extension to the Java reflection API. It enables structural reflection in Java, allows to alter a given class definition and to dynamically define a new class. Language extensions are more easily implemented with structural reflection than with behavioral reflection.

27 Conclusions (Cont.) JavAssist is portable. JavAssist provides source-level abstraction for manipulating byte code in a safe manner, while byte code translators, such as JOIE and the JavaClass API, provide no higher-level abstraction. JavAssist processes byte code. OpenJava processes source code.

28 Conclusions (Cont.) The architecture of JavAssist can be applied to other object-oriented languages if a compiled binary program includes enough symbolic information to construct a class object. API must be individually designed for each language to allow class alteration definition in a safe and meaningful manner.

Download ppt "JavAssist X.class Class Loader My Loader X compile load JavAssist enables preload byte code modification."

Similar presentations

Ads by Google