Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Contribution Class Loading

observations on contribution class loading .... these will need distilling down when I have made some real conclusions

The ClassLoaderModelResolver (CLMR) specializes java.net.URL.URLClassLoader and implements o.a.t.s....ModelResolver.

In a simple scenario example (see SampleJSELauncher): in ClassLoaderModelResolver::resolveModel() where for example the ClassReference instance names "calculator.CalculatorServiceImpl" as an unresolved Java class. This method does a Class.forName on the named element and thereby relies on the URLClassLoaders defineClass behaviour.  (see note below on parent class loader determination)

Each contribution is associated with a single CLMR . On construction the CLMR is endowed with a set of URLs that allow it to find all classes in it's contribution via the URLClassLoader behaviour.

Wiki Markup
*T{*}he itest project import-export-tests has a class TestTestCase with method testOneNode which demonstrates a more complex scenario where a cross contribution import/export of a java package exists between the contributions.  In this example a node is created using 2 composite URIs for contributions ... "../
In a more complex scenario where imports and exports exist between contributions,  the itest project import-export-tests has a class TestTestCase with method testOneNode.  In this example a node is created using 2 composite URIs for contributions ... "../
exports/target/classes", "../imports/target/classes"
 

In the sca-contribution.xml of the exports project, the org.apache.tuscany.sca.itest.exports package is exported, and is similarly imported in the imports project. The Export project exports the interface HelloWorld.  The import project provides the HelloWorldImpl implementation of the interface provided by the exports project. 

In starting the node, the default deployer resolves contribution dependencies.

  The contribution Content Processor resolves the HelloWorld.composite artifact

    The extensible StAX artifact processor looks inside the composite file

       The  composite processor amongst other things resolves the component implementation, in this case HelloWorldImpl.class

           The Java Implementation Processor names the class in an instance of oats.contribution.resolver.ClassReference

               The ExtensibleModelResolver determines that the ClassLoaderModelResolver is the thing to resolve a java implementation artifact (so far this is just like the simple scenario)

The ContributionURLs are determined to be the classes iunder the target folder of the imports project

The parent class loader for the new ClassLoaderModelResolver is determined by the ServiceDiscovery singleton to be the thread context class loader (check to see if this is the same in the simple scenario -- i think so)

The ClassLoaderModelResolver observes that the contribution has an import of the oats.xxx.exports package

                                        it discovers it has no mapping for that package and creates a placeholder for such a mapping in the map which it holds in its state in importResolvers

             The ExtensibleModelResolver asks the CLMR to resolve the HelloWorldImpl class

                  The CLMR calls Class.forName on the impl class, suppying itself as the class loader

The Class.forName call results in the CLMR's findClass method being called

The CLMR uses its importResolvers to attempt to resolve the class, but fails

so it attempts to resolve the class from the current contribution (via the superclass function forName()) which is url based)

                                in doing so we hit the CLMR's findClass method again, but instead looking for the HellowWorld interface of the exports package

. An imported class is resolved using the CLMR of the exporting contribution.  The exporter's CLMR is made available to the importing CLMR by deployment \[1\] code which traverses all contributions, identifying cross contribution dependencies (see buildDependencies at \[1\])  and using the set of remaining contributions to resolve the import, potentially more than once.

[1 http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/deployment/src/main/java/org/apache/tuscany/sca/deployment/impl/DeployerImpl.java?view=markup&pathrev=948564Image Added|http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/deployment/src/main/java/org/apache/tuscany/sca/deployment/impl/DeployerImpl.java?view=markup&pathrev=948564]                              

                                

...