retroactive api extensions through bytecode weaving
DESCRIPTION
Retroactive API Extensions Through Bytecode Weaving . Jevgeni Kabanov PhD student, University of Tartu. WHAT?. API Extensions Application programming interface New APIs, changed APIs Bytecode Weaving Bytecode : stack-based Java-like language Weaving: runtime program rewriting - PowerPoint PPT PresentationTRANSCRIPT
Retroactive API Extensions
Through Bytecode Weaving Jevgeni Kabanov
PhD student, University of Tartu
WHAT?API Extensions
Application programming interfaceNew APIs, changed APIs
Bytecode WeavingBytecode: stack-based Java-like language Weaving: runtime program rewriting
RetroactiveAbstraction after the factWithout access to source code
WHY?Java EE is implemented by application containers each with specific extensions
Frameworks and applications need a unified access to container-specific features
EXAMPLEJavaScript, DOM, abstraction libraries
GWTPrototypejQueryExt JS
Spring (Java framework)Abstraction over some common Java EE features for applications
BEHIND THE SCENES
MyObject.class
MyObject.classMyClass_
3MyClass’MyClass
IDEs Servers Frameworks
Open-Source API
Class loader APIpublic abstract class ClassLoader { public Class loadClass(String name); protected Class defineClass(byte[] b);
public URL getResource(String name); public Enumeration getResources(String
name);
public ClassLoader getParent()}
API ExtensionsChange loadClass() to include the classes we provide to it
Add a method getChildResources() that returns the resources hierarchically
Java Class Definition
Modifiers, name, super class, interfacesEnclosing class referenceAnnotation*Inner class* NameField* Modifiers, name, type
Annotation*Method* Modifiers, name, return and parameter types
Annotation*Compiled code
Java Execution Model
Method B
Method A
MainL0 L1 L2 L3O1 O2
L0 L1 L2O1 O2 O3
L0 L1O1
Local variables
Operand stack
Execution stackFrame
Calli
ng a
met
hod
Thro
win
g an
ex
cept
ion
Instruction Example
INVOKEINTERFACE java/util/List get (I)LObject;
opcode arguments
... java.util.List int ... java.util.List.get(int)apply
Operands stack when applying the instruction:
Instruction:
Hello, World! in Bytecodepublic class HelloWorld { public <init>()V ALOAD 0 INVOKESPECIAL Object.<init>()V RETURN public static main([LString;)V GETSTATIC System.out : LPrintStream; LDC "Hello, World!" INVOKEVIRTUAL PrintStream.println(LString;)V RETURN}
REWRITING IS EASYASM
Visitor APILow level
JavassistString-embedded Java DSL High-level, but adjustable
PROBLEM 1: TRANSPARENCYIf the result of an API call is altered, how do we access the original from our framework?
E.g. ClassLoader.loadClass()
PROBLEM 2: OPTIONALWhat if the features we want to support are optional or implemented differently among implementers?
E.g. ClassLoader.getChildResources()
PROBLEM 3: VERSIONINGWhat if we have several versions of an implementation?
NB! In Java the class files are not versioned and detecting versions may be challenging
PROBLEM 4: GLOBAL STATEWhat if implementer state dictates that calls are legal in some states and illegal in others?
E.g. ClassLoader classpath is often constructed incrementally
PROBLEM 5: SYNCHRONIZATION
What if implementer does synchronization?
Synchronized in Java is a reentrant mutexClassLoader.loadClass() is synchronized, ClassLoader.getResource() usually not
Questions?