Chapter 1. Bundle Class Loader
Abstract
This chapter introduces some basic OSGi class loading concepts. Ultimately, in order to understand the relationship between a bundle and its dependencies, and to understand the meaning of importing and exporting packages, it is essential to learn about the bundle class loader.
1.1. Class Loader Basics
Overview
If you are concerned about which version of a class your application uses, you inevitably have to start dealing with class loaders. In Java, the class loader is the mechanism that controls where class definitions come from and decides whether or not to allow a particular class definition to be used. So, when it comes to versioning and security, class loaders play a central role.
Because version control is also important in OSGi, it follows that class loaders play a key role in the OSGi architecture. One of the main aims of OSGi is to make class loading more flexible and more manageable.
Bundle class loader
A fundamental rule in OSGi is that every bundle has its own class loader and this class loader is known as the bundle class loader.
You might wonder whether it is really necessary to have a class loader for every bundle. The class loader per bundle architecture is chosen for the following reasons:
- A class loader encapsulates knowledge about where to find classes and a particular bundle might have knowledge about finding classes that other bundles do not possess. For example, a bundle can have private classes, not directly visible to other bundles.
- In order to support the flexible OSGi class loading architecture, each bundle needs to be in control of how and where it finds its classes.
Identity of a loaded class
In the context of OSGi, where a typical application depends on multiple class loaders (one for each bundle), it is important to understand that the fully-qualified class name—for example,
org.foo.Hello
—is not sufficient to identify a loaded class uniquely. In general, a loaded class is uniquely identified by combining the classloader identity with the fully-qualified class name.
For example, if the class,
org.foo.Hello
, gets loaded by the bundle classloader for version 1.3 of bundle A
, the loaded class is uniquely identified by the combination of the class loader, A;1.3
, and the class name, org.foo.Hello
. In this chapter, the following notation is used for the unique identity of the loaded class:
A;1.3/org.foo.Hello
Bundle class space
The OSGi specification defines a bundle's class space to be the set of all classes accessible to the bundle's class loader, where each class in the set is a unique instance, qualified by the class loader that loaded it.
A bundle class space includes a bundle's private classes, as well as any public classes imported from the bundle's dependencies.
Multiple copies of a loaded class
When you have multiple class loaders at parallel locations in the class loader hierarchy (which is the case with the bundle class loaders), it is actually possible to load multiple, distinct, copies of the same class.
For example, given the appropriate conditions, it is possible that version 1.3 of bundle A and version 2.0 of bundle B could both independently load the class,
org.foo.Hello
. In this case, you would have two distinct loaded classes, as follows:
A;1.3/org.foo.Hello B;2.0/org.foo.Hello
The OSGi framework is designed to prevent multiple copies of a class ever appearing in the same class space, because this almost always causes errors at run time. On the other hand, it is permissible for different copies of a class to be loaded into different class spaces. For example, it is perfectly alright for separate applications running in an OSGi container to use different versions of the same class.
Class loader delegation
One of the key class loader concepts is class loader delegation, which is where a class loader, instead of loading a class itself, asks another class loader to load the class. When class loader delegation occurs, you need to distinguish between:[1]
- Initial class loader
- The class loader that is initially asked to load the class.
- Effective class loader
- The class loader that actually loads the class, after delegation is taken into account.