Sebastien, Comments inline.
On 2/19/08, Jean-Sebastien Delfino <[EMAIL PROTECTED]> wrote: > Rajini Sivaram wrote: > > Sebastien, > > > > Contribution classloader was introduced to force isolation of > contributions. > > Prior to this, all classes were loaded using a single CLASSPATH-based > > classloader, which meant that Java classes had visibility of all classes > and > > resources that could be loaded using CLASSPATH, regardless of whether > they > > were imported explicitly from other contributions. > > That's all good, I'm happy with that isolation support, but would like > to see it in the module implementing support for import/export.java. I will commit some changes now which moves ContributionClassLoader into contribution-java. The classloader will be created when the first class from the contribution is resolved by either its ClassReferenceModelResolver or other ContributionClassLoaders. But I haven't removed the association of classloaders with contributions (explained below). > > > For Java classes in contributions, it is essential for classloading to > be > > tied with ModelResolver to ensure that classes inside contributions can > see > > classes imported from other contributions, and use the exporting > > contribution's classloader to load imported classes. This is absolutely > > necessary to avoid ClassCastExceptions and NoClassDefFoundErrors. > > Agreed that classloading should go through a ModelResolver but that does > not mean "tied with a single ModelResolver in contribution-impl", IMO > contribution-java should provide an implementation of a ModelResolver > that handles classloading as specified in the import.java export.java > statements. We need one (and only one) classloader per contribution. And this classloader needs to be able to access classloaders of all contributions that it imports from, in order to resolve classes. We also have model resolvers - one ClassReferenceModelResolver per contribution is created when the first class from the contribution is resolved. We have two choices for classloading: 1. ContributionClassLoader loads classes from its own contribution, and if it cannot find it, it can use the standard model resolver code to search other contributions which export the package. This essentially means that classloading will always go through ExtensibleModelResolver (since there is no way to get to the contribution's ClassReferenceModelResolver directly). And this affects not just classes loaded by Tuscany, but all classloading inside applications loaded as contributions. 2. ContributionClassLoader loads classes from its own contribution and also searches other exporting contributions using their contribution classloader, bypassing the model resolver. This relies on contribution classloader being able to get to the classloaders of exporting contributions (currently Contribution.getClassLoader()). At the moment, we use 2) rather than 1). Apart from the performance impact of using extensible model resolver for all classloading, I don't believe that the Tuscany model resolvers handle cycles in import/exports properly. This may not be an issue with other artifact resolution where the artifacts are always expected to be found, and all resolution is explicitly triggered by an application or Tuscany. For classloading, searching for non-existent classes, expecting to obtain a ClassNotFoundException is used routinely in Java code, including inside Tuscany. And classloading is implicitly trigerred by the VM. IMO, running into stack overflows in classloading is unacceptable regardless of whether the import/export statements contained unexpected cycles and regardless of the fact that an application was trying to load a non-existent class. The current model resolution code cannot handle packages that are split across multiple contributions (and before you say why would anyone want to split packages across contributions, this was one of the problems I first ran into when trying to run Tuscany under OSGi since Tuscany modules do use split-packages). In order to use 2), contribution-java needs some way of obtaining the classloader of exporting contributions. Since there is currently no way for contribution-java to get directly to the ClassReferenceModelResolver from a contribution, the classloader is still associated with the contribution. So Contribution.java still contains getClassLoader and setClassLoader, but these are only used by contribution-java. Can you suggest a better way to get/set classloaders for contributions which can be contained inside contribution-java? > > > > I assumed (probably wrongly) when I wrote the contribution classloader > that > > Java classes inside contributions also have visibility of resources that > are > > imported using import statements other than import.java. > > For example, if I have > > > > Contribution A: > > <import.java package="x.y.z" /> > > <import.resource uri="a.b.c" /> > > Contribution B: > > <export.java package="x.y.z" /> > > Contribution C: > > <export.resource uri="a.b.c" /> > > > > > > Is there a difference between what is visible to ContributionA > (everything > > from A, package x.y.z from B and resource a.b.c from C) and what is > visible > > to classes from Contribution A? I assumed that they should be the same. > If > > classes from ContributionA should not be allowed to load the resource > > a.b.csince there is no < > > import.java/> statement for the package containing the resource, > > classloading code can be moved to contribution.java. > > > > Sorry, I may be missing something, but I'm a little lost here: > > - import.resource is not implemented yet, Luciano is just starting to > implement it. > > - its syntax should not be uri="a.b.c" as this is a Java package syntax, > I'd expect to see something like a/b/c.html instead. > > - when it gets implemented I fail to see why it should be tied to or > require a class loader. > > - what can be loaded by a Java classloader, .class files, .gif files or > whatever should be controlled by import/export.java. > > - finally, import.resource should be in a contribution-resource > extension like the other extensions... not in contribution-impl. Sorry, I did mean a/b/c. And I wasn't talking about import.resource in particular. I meant any import which resulted in a resource being imported from another contribution. I wasn't referring to Tuscany loading the resource, since that would be done using a model resolver. I was referring to an application loading the resource using something like myClass.getClassLoader().getResource("a/b/c.xml"). Should this require an < import.java package="a.b"/>? From your response, I gathered that the answer is yes. So the new code will allow applications to load resources using their classloader only if there are explicit <import.java/> statements for the directory containing the resource. -- > Jean-Sebastien > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > -- Thank you... Regards, Rajini