Title: Negligent Class Loaders for Software Evolution
1Negligent Class Loaders for Software Evolution
- Yoshiki Sato, Shigeru Chiba
- (Tokyo Institute of Technology and
- Japan Science and Technology Corp)
2Java 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
3Java 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
4The 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
5Why 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
6ProposalNegligent 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
7ProposalNegligent 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
8ProposalNegligent 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
9ProposalNegligent 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 doesnt 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
10Changing 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
object
a
a
a
SHF
b
b
SHF
TIB
c
compatible
11Additional 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()
Elder NCL
Younger NCL
12Two 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
13Conclusions
- 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
- gt flexible but slow
Our goal
Extensibility
Static typing Java,C,C -gt fast but inflexible
Runtime overhead
14Difficult 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