Question

I found the following loaders structure for OSGi in internet.

bootstrap classloader (Java standard libraries from jre/lib/rt.jar etc)
^
extension classloader
^
system classloader (ie stuff on $CLASSPATH, OSGi core code)
^ (** limited access to types from parent classloader
common OSGi classloader:
--|-- OSGi classloader for bundle1 -> (map of imported-package->classloader)
--|-- OSGi classloader for bundle2 -> (map of imported-package->classloader)
--|-- OSGi classloader for bundle3 -> (map of imported-package->classloader)

Here it says that

A context classloader set on the executing thread. By default it is always set to System classloader or from the thread from where the new thread instance was created.

From structure above we see system loader(=context loader) has higher position and as I know parent classloader never asks its children.

So my question please explain how current thread works with classes that are in current bundle?

Était-ce utile?

La solution

In OSGi the Thread Context ClassLoader (TCCL) is simply undefined. You cannot expect or assert that it will be anything in particular. In fact, a lot of the time it will be null.

TCCL is a hack that was added in Java 1.2 to support J2EE. Specifically it was needed to support things like Entity Beans; in a modern world it's used to support technologies like JPA, JAXB, Hibernate and so on.

The issue with parent delegation is that, while the application classes at the bottom have visibility of all classes in the parent classloaders, unfortunately the classes loaded by the parent classloaders do not have visibility of the application classes. In practical terms, this means that your application code can load (say) the classes that make up Hibernate, but Hibernate would not be able to load your domain classes because they are below it in the hierarchy.

So, TCCL was invented. In a J2EE application server, the TCCL is created as a thread-local variable, and it has visibility of all your application classes. Hibernate/JPA/JAXB etc can consult the TCCL in order to find the application classes. This was easy enough to do in J2EE because the app server controls all of the entry points: it controls the web server, it controls the RMI endpoints, and as an application developer you are not permitted to create your own threads.

However the programming environment for OSGi is far less constrained. Any bundle is permitted to create its own network endpoints, spin up its own threads, or pretty much do anything. Therefore, OSGi has no opportunity to intervene and impose a TCCL that has visibility of the application classes. Furthermore, the very concept of an "application" is fuzzy because we have this neat thing called modularity. An application consists of multiple bundles... but how to define which bundles may provide classes to the TCCL?

So OSGi basically punts on this issue. The TCCL is undefined so you should never rely on it. Fortunately most libraries that try to use only do so as one of a series of places they try to load classes from.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top