*Classloading in Tuscany - Application contribution classloaders*

*Current implementation*

Application classes from contributions are loaded by Tuscany in
ClassReferenceModelResolver. At the moment, this uses the thread context
classloader, which is typically set as the Java application classloader
(based on CLASSPATH). So contribution classes are only loaded if found on
the classpath. And there is no restriction on visibility across application
contributions (the import/export statements in sca-contribution.xml have no
effect on class visibility).

*Requirement for application classloading*

SCA specification requires contribution import/exports to be explicitly
specified in sca-contribution.xml. There is no parent-child relationship
between contributions, so the class-space visible to an application
contribution consists of all the classes in the contribution plus all its
imported packages (similar to OSGi bundles). SCA contributions can refer to
classes that are not contained in SCA contributions - so unlike OSGi
bundles, SCA contributions require access to classes specified on CLASSPATH.

It should be possible for application classes in one contribution to refer
to classes in other contributions, without resorting to dynamic
classloading. Dynamic classloading will automatically work using the
contribution classloader once the static visibility is sorted out.

*Proposed changes*

SCA contribution import/export spec cannot be implemented using a standard
Java parent-child classloader delegation model. But SCA contribution
import/export spec is a subset of OSGi package import/export (wiring of
import/export is more complex in OSGi since it includes versions and other
attributes). Hence an OSGi-style classloader is ideal for Tuscany to enforce
SCA contribution spec.

Each contribution will have an associated classloader. This will be an
subclass of URLClassLoader, and will have the Java application classloader
based on CLASSPATH as its parent (the parent classloader will be obtained
from the thread context). The defining classloader for any application class
will be the classloader corresponding to the SCA contribution containing the
class. ContributionClassLoader.findClass will search the contribution for
the class, and if not found, it will search other classloaders of other
contributions wired using SCA import/export. Like OSGi, an overlapping class
space will be defined for each contribution which consists of the classes in
the contribution and imported packages from other contributions.

Unlike the other proposed classloading changes which retain the ability to
use a single classloader, this change will remove the option of loading
applications using a common thread context or application classloader.

*Testing*

   1. Verify that existing tests and samples work without change.
   2. Verify that imported packages are visible from contributions (both
   static and dynamic loading).
   3. Verify that packages which are not explicitly imported from another
   contribution are not visible.
   4. Verify that contribution classes can be loaded even if they are not
   on CLASSPATH

 *Questions*

   1. It is necessary to have separate classloaders for contributions to
   enforce the SCA contribution spec. But for application isolation, it is
   sufficient o have one classloader per contribution? What is an APPLICATION
   in Tuscany? Should the isolation be at the composite level rather than
   contribution level?
   2. Is there a better way for Tuscany contributions to specify external
   dependencies instead of using CLASSPATH? The downside of having Java
   application classloader as the parent of contribution classloaders is that
   there can potentially be two classes with the same qualified name reachable
   from the contribution classloader if all contributions were added to the
   CLASSPATH. This is not really a problem as long as imports/exports are
   properly specified for contributions, but it can result in
   ClassCastException or NoClassDefFoundError if unimported classes from other
   contributions are accessed by adding them to CLASSPATH.
   3. Should there be a configuration option to override this and use a
   single thread context classloader that retains the current semantics? Does
   Tuscany have any means of setting system-wide configuration options?


Thank you...

Regards,

Rajini

Reply via email to