310 likes | 329 Views
Loosely-separated “Sister” Namespaces in Java. Yoshiki Sato (Tokyo Tech., Japan Currently, Mitsubishi Research Institute, Inc., Japan) Shigeru Chiba (Tokyo Tech., Japan). NO MORE ClassCastException. About This Talk…. The strict separation of Java namespaces
E N D
Loosely-separated “Sister” Namespaces in Java Yoshiki Sato (Tokyo Tech., Japan Currently, Mitsubishi Research Institute, Inc., Japan) Shigeru Chiba (Tokyo Tech., Japan) NO MORE ClassCastException 19th ECOOP 2005, Glasgow, UK
About This Talk… • The strict separation of Java namespaces • Scenario : inter-J2EE component communication • Ordinary 4 agonizing techniques • I will introduce • Sister namespace: A more sisterly namespace than ordinary standoffish one Ironically called the version barrier 19th ECOOP 2005, Glasgow, UK
The namespace design in Java is useful • Each class loader creates a unique namespace • This design well fits with a component system • Each loader loads a component into its own namespace • A component-based application can be developed and then deployed per component Naming conflicts between components can be avoided due to the separated namespace Dynamically and individually updated without restartingby recreating a new loader namespace Applets, Servlets, EJBs, Plug-ins deploy (install) components loader Tomcat, JBoss,Eclipse component framework JVM, OS,… undeploy 19th ECOOP 2005, Glasgow, UK
Problem of the current design:the version barrier • The difficulty to communicate across namespaces • Different versions are different types!! • Of course, they have no subtype relation • An object of one version can not be cast to the other version e.g.) online shopping WAR1 WAR2 OrderServlet EstimateServlet c = session.getCache(); Object o = cache.get(session); Cart cart = (Cart) o; c = session.getCache(); Cart cart = new Cart(); cart.put(item); c.put(session, cart); Cart Cart cart throws ClassCastException J2EE platform No cache!? 19th ECOOP 2005, Glasgow, UK
obj Why did the Java designers select this design ? • It guards JVMs against type-spoofing without runtime type checks • Type-spoofing may crash JVMs by accessing a non-existing member(Sun JDK1.1 had the similar security problem reported by Saraswat) • If the JVM does type checks with resolving members on every instance access, the version barrier is not needed • It is unacceptable for Java • Because the Java design prefers high-performance loader1 loader2 Cart, WAR1 Cart c = (Cart) obj; c.put(); c.remove(1); c.clear(); Cart, WAR2 put() remove(int) clear() put() remove(int) invoke m[resolve(“put”, “()V”)]; invoke m[resolve(“remove”, “(I)V”)]; invoke m[resolve(“clear”, “()V”)]; X clear() Segmentation fault c.clear() 19th ECOOP 2005, Glasgow, UK
Ordinary techniques for inter-component communications • Packaging into the same archive • Call-by-Reference using the Local Interface requires it • Delegating to the common parent • The classes are visible among all child loaders WAR1&2 WAR1 EAR WAR2 Cart Cart delegating namespace Tightly-coupled components decrease the availability and the maintainability • Delegating to the receiver • The JBoss UCL is based on it • Inter-process communication • Call-by-Value using the Serialization WAR1 WAR1 WAR2 WAR2 Remote call Cart Cart Cart Cart delegating Performance overheads caused by a remote call Uniquely separated namespaces are combined 19th ECOOP 2005, Glasgow, UK
Our motivation and Goal The namespace design in Java is not so bad • Our goal is relaxing the version barrierbetween compatible versions of a class • Our challenges: • Reducing runtime type checks for type-safe instance accesses • Avoiding tightly-coupled namespaces • Keeping lazy class loading But the version barrier is so bad…hmm 19th ECOOP 2005, Glasgow, UK
Sister namespace • Sister namespaces can relax the version barrier • between sibling namespaces • explicitly specified against class loaders by the programmers • Version barriers between the version compatible classes are automatically and silently relaxed • Incompatible classes can be also loaded into each own namespace if they are harmless to the other namespace by using protected ClassLoader(ClassLoader parent, ClassLoader sister) sister1 sister2 incompatible, but loaded parent compatible, thus relaxed We aren’t nagging, loosely-separated 19th ECOOP 2005, Glasgow, UK
Sister namespace • A sister relation is established only among the namespaces that have no parent-child relation • Our requirements are fulfilled • Runtime type checks are reduced • Lazy class loading are kept • Tightly-coupled namespaces are avoided All classes in sister namespaces satisfy bridge-safety sister1 sister2 incompatible, but loaded parent compatible, thus relaxed We aren’t nagging, loosely-separated 19th ECOOP 2005, Glasgow, UK
Version compatibility • Version compatible changes • The differences that an instance can be securely accessed through another version of that class • Any static members (static methods, static fields,constructors, initializers) • A body of instance members (instance methods) • Derived from the study of Java binary compatibility • If the binary compatibility satisfied, a class can link preexisting binaries without recompiling. • If the version compatibility satisfied, an instance rather than a class can work with the binary of another version Cart,WAR1 Cart,WAR2 cart cart 19th ECOOP 2005, Glasgow, UK
Only few instructions do runtime checks because of bridge-safety • The bridge-safety property is satisfied [Saraswat’97] • An instance from the sister namespace must be • upcast to their supertype loaded by their common parent loader • downcast to a variable of the corresponding class type • The version checker has only to work with the type checker • All instances cross the version barrier through checkcast • The version checker implies no performance penaltiesunless instances are passed across the version barrier Regular type-check algorithm WAR2 WAR1 if LHS is a subtype ofRHS true elseif LHS is not a subtype ofRHS false end System class loader checkcast Object if LHS is a sister type of RHS && LHS is version compatible with RHS Cart Cart (Cart)cache.get(…) cache.put(cart) Version check algorithm 19th ECOOP 2005, Glasgow, UK
Sister loader constraints can delay version checks • The version checker requires eager class loading • Untrusted instances may relay an incompatible instance • As a field, a method return, and a method argument value • All relayed classes must be eagerly loaded and then verified for winning the trust of the relaying instance • The constraints for the non-loaded classes • The version checker recursively verifies version compatibility • While recording the constraints for the non-loaded classes Loaded Non-loaded class Cart { ProductMap map = null; ProductList getProducts() {…} void putProduct(Product product) {…} } class Cart { ProductMap map = null; ProductList getProducts() {…} void putProduct(Product product) {…} } class Cart { ProductMap map = null; ProductList getProducts() {…} void putProduct(Product product) {…} } class Cart { ProductMap map = null; ProductList getProducts() {…} void putProduct(Product product) {…} } cart Sister1 Sister2 Sister namespaces 19th ECOOP 2005, Glasgow, UK
Sister loader constraints can delay version checks • The version checker verifies • <Cart, SN1> can trust <Cart, SN2> • <Cart, SN1> is version compatible with <Cart, SN2> • <ProductMap, SN1> can trust <ProductMap, SN2> • <ProductList, SN1> can trust <ProductList, SN2> • <Product, SN1> can trust <Product, SN2> • Casting <Cart, SN1> to <Cart, SN2> succeeds • If both loaded, the sister loaders verify • <ProductMap, SN1> can trust <ProductMap, SN2> • <ProductList, SN1> can trust <ProductList, SN2> Sister loader constraints New constraints Loaded Non-loaded class Cart { ProductMap map = null; ProductList getProducts() {…} void putProduct(Product product) {…} } class Cart { ProductMap map = null; ProductList getProducts() {…} void putProduct(Product product) {…} } cart Sister1 Sister2 Sister namespaces 19th ECOOP 2005, Glasgow, UK
put put compatible remove remove clear clear Schema compatible loading • The instances may have schema inconsistencies • The layout of TIBs(type information block) may not be identical • The TIBs of both versions are updated to be compliant with each other when both versions are loaded • The corresponding members share the same index into the TIB • All members can be correctly accessed without any checks Cart, WAR1 Cart, WAR2 put() remove(int) clear() remove(int) clear() put() hold fields and function pointers to a corresponding method body tib[0] put remove tib[1] remove clear tib[2] clear put 19th ECOOP 2005, Glasgow, UK
Implementation on the IBM Jikes RVM • The extensions to the JRVM • Java API • GNU Classpath libraries • Sister loader 1. Examines version compatibility 2. Performs schema compatible loading 3. Verifying sister loader constraints • Version checker 1. Version checks 2. Verifying sister loader constraints • Class and object(TIB) representations • An identifier of a sister relation • Sister’s superclasses and interfaces [Java.lang.ClassLoader] protected ClassLoader(ClassLoader parent,ClassLoader sister) TIB Class type type ID sister super static member interfaces sister’s super sister’s interface vmethod Object field TIB status 19th ECOOP 2005, Glasgow, UK
Related work • Most of the previous researches regarded the version barrier as a temporal boundary between old and new components • HotSwap Sun JDK1.4 JPDA (JDK1.5 java.lang.instrument) • Dynamic Java Classes [Malabarba00ECOOP] • Dyamic Classes [Hjalmtysson98USENIX] • The spatial version barrier among multiple components, where an older version remains after a new version is loaded • Reclassifying object [Drossopoulou01ECOOP] • Wide classes [Serrano99ECOOP] • Type-based hotswap [Duggan01ICFP] • Dynamic typing language (CLOS, Self, Smalltalk) Dynamic software updates and evolution Explicit type changing semantics 19th ECOOP 2005, Glasgow, UK
Concluding remarks • The design and implementation of loosely-separated “sister” namespaces in Java • Melts the Java’s strong types only at the joint of components • We are now formalizing and proving the type soundness • It could adopt to the dynamic AOP system, which is for not DI + AOP but DI x AOP • Our experimental results show • The baseline overhead was negligible • -5~5% running the SpecJVM98 on the modified JRVM • The version check overheads are not so severe • 1st : 1,000~4,000 % • 2nd : 160% using the results of 1st 19th ECOOP 2005, Glasgow, UK
The End Thank you for your attentions !! If any questions, please ask me “clearly” and “slowly” 19th ECOOP 2005, Glasgow, UK
Compatibility with JIT compilers • Canceling JIT compilations • Optimizing JITs transform a virtual method to a static one • Such a devirtualized and maybe inlined method call does not correctly refer to a method declared in a sister version • Recent JITs cancel devirtualization efficiently by rewriting or replacing an inlined code when a new sister loaded Cart c = (Cart) obj; Inlined_put(); Inlined_remove(1); Inlined_clear(); obj Cart, WAR1 Cart, WAR2 put() remove(int) clear() put() remove(int) clear() Devirtualized and maybe inlined 19th ECOOP 2005, Glasgow, UK
Eager notifications of version incompatibility • The incompatibility errors are eagerly thrown • Version checking • Or, class loading • The linker is no use for the sister classes that have already linked with a call site • Unlike the binary compatibility checks in Java • Like the loader constraint scheme Sister namespaces class Cart { ProductMap map = null; ProductList getProducts() {…} void putProduct(Product product) {…} } class Cart { ProductMap map = null; ProductList getProducts() {…} void putProduct(Product product) {…} } cart Loaded Version Incompatible 19th ECOOP 2005, Glasgow, UK
memo • Q) Why did you use “sister” as the name? • A) Using the notion of “sister”, we can imagine a more soft and friendly sibling relation than brother. • Q) How do you deal with the co-variant and contra-variant problems? • A) There is no sub-typing relation between sister versions of a class type, that is, one is neither the other’s supertype nor subtype. So the co-variant and contra-variant problems are not need to be regarded. • Q) What is the difference from the loader constraint scheme? • A) The loader constraint scheme rather strenghthens the version barrier, while our work relax the version barrier • Q) OODB? • A) In the object database community, several schema evolution techniques such as schema or class versioning have been studied. Using the object databases is a workable alternative. • Q) Why not the performance overheads are severe? • A) We think the overheads are not so severe compared to the inter-component communication. Just for a reference, we measured the costs of the inter-component communication. We transported 400KB files over network and it spent 3 million times larger than checkcast • Q) Why not a sister relation is allowed between a parent-child? The bridge-safety property is not satisfied for all the classes. What could be wrong? • A) Since all classes included in the parent are visible for the child class loaders, the instances can be passed without the checkcast operation, by using just an assignment operation. 19th ECOOP 2005, Glasgow, UK
pronunciation • Separately • Violate • Inconsistencies • Incompatibility • Examine • Identification • Determine • Alternative • Simultaneously • Spatial • Cause 19th ECOOP 2005, Glasgow, UK
About This Talk… • The strict separation of Java namespaces • Scenario : inter-J2EE component communication • Our goal • Relaxing the version barrier • while still allowing type-safe instance accesses • with negligible performance penalties in regular execution • Melting the strong types • only at the joint of namespaces (components) • I will introduce • Sister namespace: A more sisterly namespace than ordinary standoffish one Ironically called the version barrier 19th ECOOP 2005, Glasgow, UK
Ordinary techniques for inter-component communications • Packaging into the same archive • Using the Local Interface introduced by EJB 2.0 requires it • It enables using Call-by-Reference on the local communication • Delegating to the common parent • The classes loaded by a loader areavailable for that all child loaders • The WAR components can share the same version loaded for the EAR Tightly-coupled components decrease the availability and the maintainability WAR1&2 Cart WAR1 EAR WAR2 Cart delegating namespace 19th ECOOP 2005, Glasgow, UK
Ordinary techniques for inter-component communications • Delegating to the receiver (JBoss UCL ) • A collection of UCLs acts as a single class loader, which places into a single namespace all the classes to be loaded • All classes are loaded into the sharedrepository and managed by it Uniquely separated namespaces are combined • Inter-process communication (Call-by-Value) • It uses the Serialization API to exchange objects between different components through a byte stream • Typical J2EE platforms adopt this approach as the last resort Performance overheads caused by a remote call WAR1 WAR2 Cart Cart delegating WAR1 WAR2 Remote call Cart Cart 19th ECOOP 2005, Glasgow, UK
Sister namespace can relax the version barrier • The design of sister namespaces • Namespaces except the parent and child can be sisters • The version barrier between the version compatible classes are silently and automatically relaxed in the sister namespace • Runtime type checks for type-safe instance accesses are reduced • Each sister needn’t mind the other’s loading of incompatible but harmless classes sister1 sister2 parent All classes in the sister namespace satisfy bridge-safety incompatible, but loadable compatible, so exchangeable We aren’t nagging, loosely-separated 19th ECOOP 2005, Glasgow, UK
Sister namespace • Version barriers between the version compatible classes in sister namespaces are automatically relaxed • Explicitly specified against class loaders • Established among namespaces that have no parent-child relation • Our requirements are fulfilled • Runtime type checks are reduced • Lazy class loading are kept • Incompatible classes are loaded into each namespace if harmless to the other namespace sister1 sister2 incompatible, but loaded All classes in sister namespaces satisfy bridge-safety parent compatible, thus relaxed We aren’t nagging, loosely-separated 19th ECOOP 2005, Glasgow, UK
Sister namespace • Sister namespaces can relax the version barrier between the sibling namespaces pairing in advance • Only secure instances can be assigned to the variable of the sister version of that class type • The programmers explicitly specified sister relations: protected ClassLoader(ClassLoader parent, ClassLoader sister) 1. Version compatibility WARLoader(EAR, WAR1) WARLoader(EAR) EARLoader() Cart,WAR1 Cart,WAR2 cart 3. Sister loader constraints 2. Version checker 4. Schema compatible loading 19th ECOOP 2005, Glasgow, UK
Version checker • The version checker, an extension to the built-in type checker, is what relaxes the version barrier • Checks the sister relation and the version compatibility • Only several instructions require dynamic type checking(instanceof, checkcast, invokeinterface, athrow) • Other instructions are statically typed (invokevirtual, getfield, etc.) • This implies no performance penaltiesas long as the version checks are not performed if LHS is a sister type of RHS && LHS is version compatible with RHS true else false end if LHS is a subtype ofRHS true elseif LHS is not a subtype ofRHS false end Version check algorithm Regular type check algorithm 19th ECOOP 2005, Glasgow, UK
Is the version checker enough for detecting an incompatible class? • YES, because of the design of sister namespaces • No parent-child relationship between any sister namespace • The common parent namespace always exists among sisters (The top-level namespace is created by the bootstrap loader) • Bridge-safety property is satisfied [saraswat’97] • An instance from the sister namespace must be • upcast to their supertype loaded by their common parent loader • downcast to a variable of the corresponding class type WAR2 WAR1 checkcast (version check) EAR boot strap cache.put(cart); (Cart)cache.get(…); Cache Cart Cart 19th ECOOP 2005, Glasgow, UK
Concluding remarks • Sister namespace • The design and implementation of loosely-separated Java namespaces • Melts the strong types only at the joint of components • It could adopt to the dynamic AOP system, which is for not DI + AOP but DI x AOP • Our experimental results show • The baseline overhead was negligible • -5~5% running the SpecJVM98 on the modified JRVM • Loading costs depend on the number of declared members • 13~67% overheads for loading 72~1,548 classes • The version check overheads are not so severe • 1st : 1,000~4,000 % • 2nd : 160% using the results of 1st JDOM, Crimson, jaxen, dom4j, SAXON, XT, XercesJ1, 2, XalanJ 19th ECOOP 2005, Glasgow, UK