Monday, February 28, 2011

Thread Context Class Loading in Virgo

A number of popular open source libraries, particularly persistence providers, use thread context class loading to load application types. This is an issue in OSGi once an application is divided into more than one bundle. Each bundle has its own class loader and no particular one of these bundle class loaders is necessarily suitable for loading all the application classes that libraries need to load.

Virgo overcomes this problem with its notion of a scoped application. A scoped application consists of either a PAR archive file containing the application artefacts (bundles, property files, plans, etc.) or a scoped plan referring to the application  artefacts. The scope limits the visibility of application packages and services so that scoped applications do not interfere with each another. But Virgo also creates an additional synthetic context bundle for each scope and it's this bundle's class loader which is used for thread context class loading when the application calls out to libraries.

The synthetic context bundle is very simple. It's a bundle which uses Virgo's import-bundle manifest header to import each of the bundles in the scope. Thus all the packages exported by the application are available for thread context class loading by libraries. There is a minor restriction implied by this approach: no two bundles in a scoped application may export the same package, which would be pretty unusual.

The following example should help make things clear:

An Example Scoped Application
Here a scoped application contains two bundles A and B. A calls B which calls out to a library bundle L. If L uses the thread context class loader to load application types, it will have access to all the packages exported by bundles A and B. The synthetic context bundle, which imports bundles A and B, provides the thread context class loader for the scoped application.

This simple solution enables a variety of existing open source libraries, once converted to OSGi bundles, to function correctly in their use of thread context class loading.


Tim Diekmann said...

Interesting approach.

Doesn't this require that both A and B are aware of this synthesized bundle and have the code logic to set the TTCL before making any calls.
Or is Virgo making this somehow transparent to the client?

Thanks, Tim.

Glyn said...

Virgo makes this transparent to the application by setting the TCCL before each bundle is started and ensuring that the TCCL is propagated appropriately to other threads.

Glyn said...
This comment has been removed by the author.
Graham Charters said...

Hi Glyn, does this approach rely on the use of proxying by Spring or Blueprint in order to add the TCCL, or will a programmatic service lookup and call also have the TCCL set?

Thanks, Graham.

Glyn said...

Hi Graham. It relies on Blueprint. Regards,
PS. Sorry for the very late response - I stopped getting comment moderation emails for some reason.

