I have a question about the usage of Java ClassLoader in OSGi.
I wrote two OSGi bundles, namely server bundle and client bundle.
In server bundle, I implemented
You said: "In my knowledge, when class B is referenced in class A, the classloader of class B is the same as class A's classloader. But in OSGi, it seems not this way."
This is not a true statement about Java classloaders... whether or not you are using OSGi.
For example, every class you write extends from java.lang.Object
. Your class is loaded by the application classloader, but java.lang.Object
is loaded by the boot classloader. This works because of delegation: one classloader can ask another classloader to load a class on its behalf.
In OSGi it's exactly the same thing. Each bundle has a classloader, and when you import a package from another bundle, that other bundle's classloader is used to load them.
This is completely normal in OSGi. In OSGi there is one classloader per bundle. This classloader serves all classes that are located in the bundle. For all classes outside the bundle there are Import-Package definitions. At runtime each package import is wired to a bundle that exports the package. When a class from such a package is loaded the loading is delegated to the other bundles classloader.
Lets go through your scenario.
Bundle osgi-server contains the class com.cisco.ruan.server.HelloService it also export the package com.cisco.ruan.server. Bundle osgi-client imports the package com.cisco.ruan.server. When you load the HelloService class in the Activator of osgi-client the classloader of osgi-client is asked to load the class. It finds a delegation for the package and delegates loading to the classloader of osgi-server. This classloader is then user to load the class.
This is the default behaviour in OSGi and if you think it through it makes a lot of sense.