Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 1 Negligent Class Loaders for Software Evolution Yoshiki Sato, Shigeru Chiba (Tokyo Institute of Technology and Japan Science and Technology Corp)
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 2 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(); 1.Creating a custom class loader 2.Putting the logging functionality on the Product class using a translator 3.Loading the modified version of the Product class Finally, we can get an instance of the new Product class Common mistake!!!
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 3 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 We want to enable such a cast operation
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 4 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 Version barrier (i.e. namespace) product old new incompatible loader1 loader2
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 5 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) Product p = (Product) c.newInstance(); int price = p.getPrice(); Product getName() getPrice() Product getName() p 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 loader1( Segmentation fault p.getPrice() loader2(
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 6 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 2.Needs additional runtime checks but minimum 3.Negligent in updating instances Parent class loader product Elder NCL Younger NCL An instance can be assigned to a variable of the version of the pairing loader
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 7 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
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 8 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
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 9 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
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 10 Changing the class schema securely 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 caller code TIB object Compliant schema updates a b c() a() b a a c SHF 1 a() 2 b() 1 a() 2 b() A new version is loaded compatible Old New (TIB: type information block) Old
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 11 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 Elder NCL Younger NCL Parent CL Object obj = Product p = c.newInstance(); (Product) obj; checkcast
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 12 Most of previous work 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
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 13 Conclusions Runtime overhead Extensibility Static typing Java,C#,C++ -> fast but inflexible Dynamic typing CLOS,Smalltalk,Ruby -> flexible but slow Our goal We are currently implementing our approach on IBM Jikes RVM Future directions Evaluating performance overheads Handling fields and arrays of multi-versioned class The proof of type safety and Java security architecture
Jun 14, 2004RAM-SE'04 Workshop, Oslo, Norway 14 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