Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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 Retroactive Abstraction after the fact Without 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 EXAMPLE JavaScript, DOM, abstraction libraries GWT Prototype jQuery Ext JS Spring (Java framework) Abstraction over some common Java EE features for applications BEHIND THE SCENES MyObject.class MyObject.class MyClass MyClass’ MyClass_3 IDEs Servers Open-Source API Frameworks Class loader API public 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 Extensions Change 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, interfaces Enclosing class reference Annotation* Inner class* Name Field* Modifiers, name, type Annotation* Method* Modifiers, name, return and parameter types Annotation* Compiled code Java Execution Model Method B Calling a method Throwing an exception L0 Local variables L1 Operand stack O1 Method A L0 L1 L2 Frame O1 O2 O3 Execution stack Main L0 L1 O1 O2 L2 L3 Instruction Example Instruction: INVOKEINTERFACE java/util/List opcode get (I)LObject; arguments Operands stack when applying the instruction: apply ... java.util.List int ... java.util.List.get(int) Hello, World! in Bytecode public 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 EASY ASM Visitor API Low level Javassist String-embedded Java DSL High-level, but adjustable PROBLEM 1: TRANSPARENCY If the result of an API call is altered, how do we access the original from our framework? E.g. ClassLoader.loadClass() PROBLEM 2: OPTIONAL What if the features we want to support are optional or implemented differently among implementers? E.g. ClassLoader.getChildResources() PROBLEM 3: VERSIONING What 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 STATE What 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 mutex ClassLoader.loadClass() is synchronized, ClassLoader.getResource() usually not Questions?