Classloading and Type Visibility in Osgi: Mtili T Martin Lippert Akquinet It-Agile GMBH
Classloading and Type Visibility in Osgi: Mtili T Martin Lippert Akquinet It-Agile GMBH
Martin
M ti Lippert
Li t
akquinet it-agile GmbH
[email protected]
© 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license | November 4th, 2008
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
What is Classloading?
• Classloaders are Java objects
• They are responsible for loading classes into the VM
Every
y class is loaded byy a classloader into the VM
There is no way around
• Every class has a reference to its classloader object
myObject.getClass().getClassLoader()
Obj t tCl () tCl L d ()
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Classloader API
public abstract class ClassLoader {
p
public URL g
p getResource(String
( g name)
)
public Enumeration<URL> getResources(String name)
public InputStream getResourceAsStream(String name)
...
}
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
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
Dynamic class loading
...
}
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Hierarchical classloaders
• Classloaders typically have a parent classloader
Chained classloading
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Classloader hierarchy
Class A
Classloader A A.jar
parent
Class B
Classloader B
B.jar
loaderB.loadClass("A");
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Type compatibility
Class A
Classloader A A.jar
loaderA.loadClass("A");
parent
Class B
Classloader B
B.jar
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
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
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
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”)
Class B Class B
Classloader B1 Classloader B2
B.jar
j B.jar
j
public class B implements A {}
A anA = loaderB1.loadClass(
loaderB1.loadClass(“B”).newInstance();
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
The default setting
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
A typical setting…
bcel oracle json
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Threads context classloader
Thread.currentThread().getContextClassLoader()
Thread currentThread() getContextClassLoader()
Thread.currentThread().setContextClassLoader(..)
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
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
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
• Some
S people
l say th
the classloading
l l di mechanism
h i iis th
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
Classloading in OSGi
• “OSGi
OSGi is a service framework”
framework
• What is necessary:
Dependencies between bundles
Import- and Export-Package, Require-Bundle
Dynamic Bundle Lifecycle
Install, Update, Uninstall bundles
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
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
Classloader per bundle
• Effects
No linear class path for your application anymore
Instead class path per bundle
No real parent hierarchy anymore
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Dependencies via delegation
Export Package: mypackageA
Export-Package:
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
Type Visibility I
Export-Package: mypackageA
Class A
Bundle A
Class B
Import-Package: mypackageA
Bundle B
A anA = new A();
Export-Package: mypackageA
Class A
Bundle A
Class B
Import-Package: mypackageA
Bundle B
A anA = new A();
Export-Package: mypackageA
Class A
Bundle A
Class B
Import-Package: mypackageA
Bundle B
A anA = new A();
ClassNotFoundException
p
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Type Compatibility revisited I
Export-Package: mypackageA
Class A
Bundle A
Class B
Import-Package: mypackageA
Bundle B
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
Type Compatibility revisited II
Export Package:
Export-Package: Export Package:
Export-Package:
mypackageA;version="1.0.0" mypackageA;version=“2.0.0"
Class A Class A
Bundle A Bundle A
Import-Package: Import-Package:
mypackageA;version=“1
mypackageA;version= 1.0.0
0 0" mypackageA;version=“2
mypackageA;version= 2.0.0
0 0"
Class B Class C
Bundle B Bundle C
Class B
public class B impl A {}
Bundle B
Bundle C
Class D
A myA = createServiceA();
Bundle D
• Serialisation
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Libraries
org.hibernate
• What happens if a library needs B dl
Bundle
to load classes from its clients?
e.g. persistence libraries?
Bundle A
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Register classes
• Register types the library need via an API
E.g.
Hibernate.registerClass(Class clientClass)
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
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,
rarely as
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
Equinox buddy loading I
• Equinox provides so called “Buddy
Buddy Loading
Loading”
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Equinox buddy loading II
Eclipse-BuddyPolicy: registered
org.hibernate
Bundle
Eclipse-RegisterBuddy:
org.hibernate
Cl
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
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
The loading sequence
1.
1 Try the parent for “java
java.” packages
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
Garbage Collection for Classloaders
• You could expect that the classloader of a bundle gets
garbage collected if the bundle is stopped or
uninstalled
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
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
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Service Tracker helps
• Use a Service
Service-Tracker
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
“High Performance Classloading”
• Classloading consumes a remarkable amount of time
at startup
• OSGi allows to highly
g y optimize
p classloading
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
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
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Conclusions
• Changing the viewpoint from the linear classpath to a
per-bundle classpath
• Clearlyy defined dependencies
p and visibilities
Real modularity
Classloading only implementation detail
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license
Thank you for your attention!
Q&A
Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license