0% found this document useful (0 votes)
33 views

Classloading and Type Visibility in Osgi: Mtili T Martin Lippert Akquinet It-Agile GMBH

Classloaders are Java objects They are responsible for loading classes into the VM y y There is no way around Every class has a reference to its classloader object myObject.getClass().getClassLoader() Originally motivated by Applets To load classes from the server into the browser VM Classloading and Type Visibility in OSGi (c) 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views

Classloading and Type Visibility in Osgi: Mtili T Martin Lippert Akquinet It-Agile GMBH

Classloaders are Java objects They are responsible for loading classes into the VM y y There is no way around Every class has a reference to its classloader object myObject.getClass().getClassLoader() Originally motivated by Applets To load classes from the server into the browser VM Classloading and Type Visibility in OSGi (c) 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 44

Classloading and Type Visibility in OSGi

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 ()

• 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
Classloader API
public abstract class ClassLoader {
p

public Class<?> loadClass(String name)

public URL g
p getResource(String
( g name)
)
public Enumeration<URL> getResources(String name)
public InputStream getResourceAsStream(String name)

public final ClassLoader g


p getParent()
()

public static URL getSystemResource(String name)


public static Enumeration<URL> getSystemResources(String name)
public
p static InputStream
p getSystemResourceAsStream(String
g y g name)
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
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

public void foo() {


ClassLoader cl =
this.getClass().getClassLoader();
Class<?> clazz = cl.loadClass("A");
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
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
P t first
fi t strategy
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
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

Returns the same class object as


loaderB.loadClass("A")

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”)

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
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(
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

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
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
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
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

• 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
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

• 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
Dependencies via delegation
Export Package: mypackageA
Export-Package:
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
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
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
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
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
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

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
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
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
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
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
g those classes directlyy

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”

Š “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
Equinox buddy loading II
Eclipse-BuddyPolicy: registered

org.hibernate
Bundle

Allows org.hibernate bundle to


execute successfully
loadClass(“A”)

Eclipse-RegisterBuddy:
org.hibernate
Cl
Class A

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
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
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

• 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
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
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

• 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
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

• Use OSGi in a clean and correct way and you


never need to think about classloading
g at all

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

Martin Lippert: [email protected]

Classloading and Type Visibility in OSGi | © 2008 by Martin Lippert; made available under Creative Commons Att. Nc Nd 2.5 license

You might also like