140 likes | 242 Views
Negligent Class Loaders for Software Evolution. Yoshiki Sato, Shigeru Chiba (Tokyo Institute of Technology and Japan Science and Technology Corp). Common mistake!!!. Java class loaders are great!!. How do you implement dynamic AOP or reflection ? It should be easy if using class loaders.
E N D
Negligent Class Loaders for Software Evolution Yoshiki Sato, Shigeru Chiba (Tokyo Institute of Technology and Japan Science and Technology Corp) RAM-SE'04 Workshop, Oslo, Norway
Common mistake!!! Java class loaders are great!! • How do you implement dynamic AOP or reflection ? • It should be easy if using class loaders loader = new CustomClassLoader(…); byte[] modifiedclass = translator.compose(“Product”, “Logging”); Class c = loader.load(modifiedClass); Product p = (Product) c.newInstance(); • Creating a custom class loader • Putting the logging functionality on the Product class using a translator • Loading the modified version of the Product class Finally, we can get an instance of the new Product class RAM-SE'04 Workshop, Oslo, Norway
We want to enable such a cast operation Java class loaders are useless!! • This is wrong implementation • Two Product classes are loaded as different classes • The system class loader loads one class file • The CustomClassLoader loads another They have the same name but are not compatible • Some experts may define the Product class as an interface • But it is troublesome, slow and inflexible loader = new CustomClassLoader(…); byte[] modifiedclass = translator.compose(“Product”, “Logging”); Class c = loader.load(modifiedClass); Product p = (Product) c.newInstance(); ClassCastException RAM-SE'04 Workshop, Oslo, Norway
incompatible The version barrier forbids this cast • The version barrier is an obstacle to software evolution • as well as the restricted ability for reloading a class • Different versions of a class is not compatible in Java • Those are separately loaded by distinct class loaders • An instance can not be assigned to a variable of another version of a class loader1 Version barrier (i.e. namespace) old product product new loader2 RAM-SE'04 Workshop, Oslo, Norway
p Segmentation fault p.getPrice() Why did the Java designer select this ? • The version barrier guards JVMs against type-spoofing without runtime type checks • Type-spoofing may crash JVMs by accessing an illegal memory space (Sun JDK1.1 had the similar problem reported by Saraswat) loader1(http://aaa/B.jar) loader2(http://xxx/Y.jar) Product p = (Product) c.newInstance(); int price = p.getPrice(); Product getName() getPrice() Product getName() • If the JVM does type checks on every instance access, the version barrier is not needed • It is unacceptable for Java • Because the Java design prefers high-performance RAM-SE'04 Workshop, Oslo, Norway
Proposal:Negligent Class Loader (NCL) • The NCL can relax the version barrier among the sibling loaders pairing in advance • Allows changing the class schema securely • Needs additional runtime checks but minimum • Negligent in updating instances Parent class loader Elder NCL product An instance can be assignedto a variable of the version ofthe pairing loader product Younger NCL RAM-SE'04 Workshop, Oslo, Norway
Proposal:Negligent Class Loader (NCL) • The NCL can relax the version barrier among the sibling loaders pairing in advance 1. Allows changing the class schema securely • Adding, deleting and changing a method • Not allowed weakening the access restriction • Not allowed changing the class hierarchy 2. Needs additional runtime checks but minimum 3. Negligent in updating instances RAM-SE'04 Workshop, Oslo, Norway
Proposal:Negligent Class Loader (NCL) • The NCL can relax the version barrier among the sibling loaders paired in advance 1. Allows changing the class schema securely 2. Needs additional runtime checks but minimum • Compliant schema updates at class liking time • The additional type checks for the NCL are needed only when an explicit cast operator is executed 3. Negligent in updating instances RAM-SE'04 Workshop, Oslo, Norway
Proposal:Negligent Class Loader (NCL) • The NCL can relax the version barrier among the sibling loaders paired in advance 1. Allows changing the class schema securely 2. Needs additional runtime checks but minimum 3. Negligent in updating instances • The NCL doesn’t change the class versions of existing instances • Multiple class versions of instances coexist in a single namespace without using an interface • An instance keeps the initial version of the class as long as it works properly RAM-SE'04 Workshop, Oslo, Norway
Changing the class schema securely (TIB: type information block) • The TIBs of both versions are updated to be compliant with each other when a new version is loaded • The corresponding methods share the same index into the TIB • A TIB entry of a missing method is filled up with a SHF (secure handling function) e.g. RuntimeException Compliant schema updates Old 3 Old New 1 a() 2 b() 1 a() 2 b() c() a() caller code 1 A new versionis loaded a object a a SHF b b SHF TIB c compatible RAM-SE'04 Workshop, Oslo, Norway
Additional runtime checks • Only runtime checks by checkcast is extended • Different versions of the class are compatible between the pairing NCLs (relaxed version barrier) • Other instructions such as invokevirtual, getfield and astore are not extended because of the bridge-safe property An instance from the pairing NCL must be • upcast to their supertype loaded by their common parent loader • downcast to a variable of the corresponding type Parent CL Object obj = (Product) obj; checkcast Product p = c.newInstance(); RAM-SE'04 Workshop, Oslo, Norway Elder NCL Younger NCL
Two approaches for runtime evolution • Dealing with instances of multiple versions of a class • Negligent Class Loaders • Runtime instrumentation of running programs • Sun JDK1.4 JPDA (JDK1.5 java.lang.instrument) • Dynamic Java Classes [Malabarba00ECOOP] • PROSE2 [Popovicci03ECOOP] • Steamloom [Bockisch04AOSD] • Recompiling a new version of a class definition • And invalidating an old version of a class definition It implies performance penalties and spoils runtime optimizations by a JIT compiler Most of previous work RAM-SE'04 Workshop, Oslo, Norway
Conclusions • We are currently implementing our approach on IBM Jikes RVM 2.3.2 • Future directions • Evaluating performance overheads • Handling fields and arrays of multi-versioned class • The proof of type safety and Java security architecture • Dynamic typing • CLOS,Smalltalk,Ruby • > flexible but slow Our goal Extensibility Static typing Java,C#,C++ -> fast but inflexible Runtime overhead RAM-SE'04 Workshop, Oslo, Norway
Difficult issues • The existing fields must not be decreased in the new version and only a private field can be added into the new version • Because an entry of a field table is generally not a function but just an element of arrays • The SHF can not be invoked at a field access by being inserted into a field table • Inlining methods must be invalidated • Because it is not executed by referring the function tables with the specified method index • An instance can not be handled keeping its own version RAM-SE'04 Workshop, Oslo, Norway