Classloading and Type Visibility in OSGi

  • 4,038 views
Uploaded on

 

More in: Technology , Automotive
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
4,038
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
127
Comments
0
Likes
14

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Classloading and Type Visibility in OSGi Martin Li M ti Lippertt akquinet it-agile GmbH martin.lippert@akquinet.de © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license | November 4th, 2008
  • 2. Overview • Introduction to classloading What is classloading? How does classloading work? What does classloading mean for daily development? • Classloading in OSGi What is different? Dependency and visibility Advanced classloading in OSGi Some Equinox specifics • Conclusions Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 3. What is Classloading? • Classloaders are Java objects • They are responsible for loading classes into the VM Every class is loaded by a classloader into the VM y y There is no way around • Every class has a reference to its classloader object myObject.getClass().getClassLoader() Obj t tCl () tCl L d () • Originally motivated by Applets To load classes from the server into the browser VM Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 4. Classloader API p public abstract class ClassLoader { public Class<?> loadClass(String name) p public URL getResource(String name) g ( g ) public Enumeration<URL> getResources(String name) public InputStream getResourceAsStream(String name) p public final ClassLoader getParent() g () public static URL getSystemResource(String name) public static Enumeration<URL> getSystemResources(String name) public p static p InputStream getSystemResourceAsStream(String name) g y g public static ClassLoader getSystemClassLoader() ... } Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 5. Implicit class loading public class A { public void foo() { B b = new B(); b.sayHello(); causes the VM to load } class B using the } classloader of A Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 6. Dynamic class loading public void foo() { ClassLoader cl = this.getClass().getClassLoader(); Class<?> clazz = cl.loadClass(quot;Aquot;); Object obj = clazz.newInstance(); ... } Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 7. Hierarchical classloaders • Classloaders typically have a parent classloader Chained classloading • If a classloader is invoked to load a class, it first calls the parent classloader Parent first strategy P t fi t t t This helps to prevent loading the same class multiple times Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 8. Classloader hierarchy Class A Classloader A A.jar parent Class B Classloader B B.jar loaderB.loadClass(quot;Aquot;); Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 9. Type compatibility Class A Classloader A A.jar loaderA.loadClass(quot;Aquot;); parent Class B Classloader B B.jar Returns the same class object as loaderB.loadClass(quot;Aquot;) Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 10. Defining vs. Initiating classloader Defining loader Initiating loader Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 11. Type compatibility II Class A Classloader A A.jar parent parent Class B Class B Classloader B1 Classloader B2 B.jar B.jar loaderB1.loadClass(“A”) == loaderB2.loadClass(“A”) loaderB1.loadClass(“B”) != loaderB2.loadClass(“B”) Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 12. Type compatibility III Class A Classloader A A.jar parent parent Class B Class B Classloader B1 Classloader B2 B.jar B jar B jar B.jar Object b1 = loaderB1.loadClass(“B”).newInstance(); b1 !instanceof loaderB2.loadClass(“B”) Remember: a class is identified by its name (including the package name) AND its defining classloader !!! Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 13. Type compatibility IV Class A Classloader A A.jar public interface A {} parent parent Class B Class B Classloader B1 Classloader B2 B.jar j B.jar j public class B implements A {} A anA = loaderB1.loadClass(“B”).newInstance(); loaderB1.loadClass( B ).newInstance(); A anotherA = loaderB2.loadClass(“B”).newInstance(); anA = anotherA; (Assignment) Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 14. The default setting Bootstrap Classloader loads JVM classes (rt.jar) loads classes from the Extension Classloader JRE ext folder loads classes from your System Classloader application classpath Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 15. A typical setting… bcel oracle json rt content dbcp log4j jce naming aspectjrt axis jsse core logging resource plugin commons poi marketing guiapp lucene spring hibernate jdom asm cglib utils Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 16. Threads context classloader Thread.currentThread().getContextClassLoader() Thread currentThread() getContextClassLoader() Thread.currentThread().setContextClassLoader(..) • Typically used in libraries to access the context in which the library is called Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 17. Classloader.loadClass vs. Class.forName •Classloader.loadClass() Cl l d l dCl () caches the loaded class object and returns always the same class object This is done by the defining classloader This ensures that each classloader loads the same class only once •Class.forName() Class.forName() calls the normal classloader hierarchy to load the class (same happens as above) But caches the class object within the initiating classloader In standard cases no problem but can be tricky in dynamic environments Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 18. Classloading is dynamic • You can create classloaders at runtime • You can trigger them to load a specific class • For example: What app/web servers do for hot deployment •S l the l Some people say th classloading mechanism i th l di h i is the only real innovation in the Java programming language Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 19. Classloading in OSGi • “OSGi is a service framework” OSGi framework • What is necessary: Dependencies between bundles Import- and Export-Package, Require-Bundle Dynamic Bundle Lifecycle Install, Update, Uninstall bundles • Realized via specialized classloading Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 20. Classloader per bundle • One classloader per bundle Controls what is visible from the bundle Controls what is visible from other bundles Class A Classloader Bundle A Class B Classloader Bundle B Class C Classloader Bundle C Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 21. Classloader per bundle • Effects No linear class path for your application anymore Instead class path per bundle No real parent hierarchy anymore • Classloader parent setting Default: Bootstrap classloader Can be parameterized via system property Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 22. Dependencies via delegation Export-Package: Export Package: mypackageA Class A Bundle A Import-Package: mypackageA, Class B mypackageC Bundle B Class C Export-Package: mypackageC Bundle C Import-Package: mypackageA Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 23. Type Visibility I Export-Package: mypackageA Class A Bundle A Class B Import-Package: mypackageA Bundle B A anA = new A(); A anA = new A(); class A is loaded only once by class A is loaded only once by bundle A (the bundles bundle A (its defining classloader) classloader) Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 24. Type Visibility II Export-Package: mypackageA Class A Bundle A Class B Import-Package: mypackageA Bundle B A anA = new A(); A anA = new A(); class is loaded successfully (if requested inside bundle A) bundle B remains in state “installed” (not resolved), no loading of type A possible Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 25. Type Visibility III Export-Package: mypackageA Class A Bundle A Class B Import-Package: mypackageA Bundle B A anA = new A(); class is loaded A anA = new A(); successfully ClassNotFoundException p Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 26. Type Compatibility revisited I Export-Package: mypackageA Class A Bundle A Class B Import-Package: mypackageA Bundle B A anA = new A(); A anotherA = new A(); exactly the same type Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 27. Type Compatibility revisited II Export Package: Export-Package: Export-Package: Export Package: mypackageA;version=quot;1.0.0quot; mypackageA;version=“2.0.0quot; Class A Class A Bundle A Bundle A Import-Package: Import-Package: mypackageA;version= 1.0.0 mypackageA;version=“1 0 0quot; mypackageA;version=“2 0 0quot; mypackageA;version= 2.0.0 Class B Class C Bundle B Bundle C A anA = new A(); A anA = new A(); Completely different and incompatible types Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 28. Type Compatibility revisited III Type A public interface A {} Bundle A Class B public class B impl A {} Bundle B public class C impl A {} Class C Bundle C Class D A myA = createServiceA(); Bundle D Static type of myA is A, dynamic type of myA could be B or C Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 29. ClassNotFoundException • Typical reasons for a ClassNotFoundException: Dependency to declaring bundle not defined Type is not visible (not exported) • Dynamically generated classes Proxies CGLib … • Serialisation Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 30. Libraries org.hibernate • What happens if a library needs B dl Bundle to load classes from its clients? e.g. persistence libraries? • Cyclic dependencies are not Import-Package: allowed and maybe even not org.hibernate org hibernate what you want Class A Bundle A Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 31. Register classes • Register types the library need via an API E.g. Hibernate.registerClass(Class clientClass) • This allows the lib to create objects of those types without loading those classes directly g y Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 32. DynamicImport-Package DynamicImport-Package: * y p g • Works similar to Import Import- org.hibernate Package, but Bundle wiring does not happen at resolve instead at first access to such a type • Wildcards possible * allows a bundle to see Import-Package: “everything” org.hibernate Class A Should be used very rarely, as rarely a “last resort” Bundle A Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 33. Equinox buddy loading I • Equinox provides so called “Buddy Loading Buddy Loading” “I am a buddy of hibernate. Hibernate is allowed to access my types” Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 34. Equinox buddy loading II Eclipse-BuddyPolicy: registered org.hibernate Bundle Allows org.hibernate bundle to execute successfully loadClass(“A”) Eclipse-RegisterBuddy: org.hibernate Class A Cl Bundle A A anA = new A(); Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 35. Equinox buddy loading III • Important difference: Buddy loading can load all classes from a buddy bundle not only exported types • Its just a workaround for libraries and other existing code that does not behave correctly within the OSGi world • Take care: you could loose consistency Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 36. CGLib Bundle Generated Proxies • Situation: Spring Bundle Ask the Spring bundle for a bean • What does Spring? p g Creates a proxy for the bean using the classloader of bundle A using CGLib • The result The proxy type needs to be loaded by a classloader that is able to see types from Class A bundle A and CGLib Bundle A Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 37. The loading sequence 1. 1 Try the parent for “java ” packages java. 2. Try the parent for boot delegation packages 3. 3 Try to find it from imported packages 4. Try to find it from required bundles 5. Try to find it from its own class path 6. Try to find it from dynamic import 7. Try to find it via buddy loading Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 38. Garbage Collection for Classloaders • You could expect that the classloader of a bundle gets garbage collected if the bundle is stopped or uninstalled • This is not automatically the case!!! • You need to ensure that all objects from those classes loaded by this classloader are no longer referenced Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 39. What does this mean? • Example: You request an OSGi service and get an OSGi service back The service you get is provided by bundle A Next you uninstall bundle A • If you stay with your object reference to the service service, the classloader of A can never be collected Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 40. Service Tracker helps • Use a Service Tracker Service-Tracker • Takes care of … holding the reference for performance reasons As long as the service is available But B t no llonger!! Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 41. “High Performance Classloading” • Classloading consumes a remarkable amount of time at startup • OSGi allows to highly optimize classloading g y p g Finding the right class Highly optimized implementations available Avoid dynamic import Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 42. Classloading Hooks • Equinox provides a hook mechanism To enhance and modify the behavior of the runtime • Examples Modify bytecode at load-time Intercept bundle data access • Eat your own dog food Some Equinox features are implemented using those hooks e.g. Eclipse-LazyStart Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 43. Conclusions • Changing the viewpoint from the linear classpath to a per-bundle classpath • Clearly defined dependencies and visibilities y p Real modularity Classloading only implementation detail • Use OSGi in a clean and correct way and you never need to think about classloading at all g Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
  • 44. Thank you for your attention! Q&A Martin Lippert: martin.lippert@akquinet.de Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license