More Related Content
More from martinlippert (20)
Classloading and Type Visibility in OSGi
- 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
- 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