You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by an...@apache.org on 2007/10/26 15:52:37 UTC
svn commit: r588644 - in /incubator/tuscany/java/sca/modules: ./
contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/
contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/impl/
contribution-java/src/main/java/org/apa...
Author: antelder
Date: Fri Oct 26 06:52:36 2007
New Revision: 588644
URL: http://svn.apache.org/viewvc?rev=588644&view=rev
Log:
TUSCANY-1871, apply patch from Rajini Sivaram for Application contribution classloaders
Added:
incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoader.java (with props)
incubator/tuscany/java/sca/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/impl/
incubator/tuscany/java/sca/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoaderTestCase.java (with props)
Modified:
incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java
incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceModelResolver.java
incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportImpl.java
incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportListener.java
incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportImpl.java
incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportImpl.java
incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportListener.java
incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportImpl.java
incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java
incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java
incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java
incubator/tuscany/java/sca/modules/pom.xml
Added: incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoader.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoader.java?rev=588644&view=auto
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoader.java (added)
+++ incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoader.java Fri Oct 26 06:52:36 2007
@@ -0,0 +1,353 @@
+package org.apache.tuscany.sca.contribution.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.Export;
+import org.apache.tuscany.sca.contribution.Import;
+import org.apache.tuscany.sca.contribution.java.JavaImport;
+import org.apache.tuscany.sca.contribution.namespace.NamespaceImport;
+
+public class ContributionClassLoader extends URLClassLoader {
+
+ private Contribution contribution;
+
+ /**
+ * Constructor for contribution classloader
+ *
+ * @param contribution
+ * @throws MalformedURLException
+ */
+ public ContributionClassLoader(Contribution contribution) {
+
+ // To enable contributions to access code outside of SCA contributions
+ // (typically by providing them on CLASSPATH), use the thread context
+ // classloader as the parent of all contribution classloaders.
+
+ super(new URL[0], Thread.currentThread().getContextClassLoader());
+ this.contribution = contribution;
+ }
+
+
+ /**
+ * Add the URL of the contribution to the classloader search path.
+ *
+ * @param location Contribution URL
+ */
+ public void setContributionLocation(String location) {
+
+ try {
+ this.addURL(new URL(contribution.getLocation()));
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.net.URLClassLoader#findClass(java.lang.String)
+ *
+ * Search path for class:
+ * This contribution
+ * Imported contributions
+ */
+ @Override
+ protected Class<?> findClass(String className) throws ClassNotFoundException {
+
+ Class<?> clazz = null;
+ try {
+ clazz = findClassFromContribution(className);
+ } catch (ClassNotFoundException e) {
+
+ for (Import import_ : this.contribution.getImports()) {
+ if (matchesImport(className, import_, true)) {
+ // Delegate the resolution to the imported contribution
+ for (Contribution exportingContribution : import_.getExportContributions()) {
+
+ if (exportingContribution.getClassLoader() instanceof ContributionClassLoader) {
+
+ for (Export export : exportingContribution.getExports()) {
+ try {
+ if (import_.match(export)) {
+ clazz = ((ContributionClassLoader)exportingContribution.getClassLoader()).findClassFromContribution(className);
+ break;
+ }
+ } catch (ClassNotFoundException e1) {
+ continue;
+ }
+
+ }
+ if (clazz != null) break;
+ }
+ }
+ if (clazz != null) break;
+ }
+ }
+
+ if (clazz == null) throw e;
+ }
+ return clazz;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+ *
+ * Search path for class:
+ * Parent classloader
+ * This contribution
+ * Imported contributions
+ *
+ */
+ @Override
+ protected synchronized Class<?> loadClass(String className, boolean resolveClass)
+ throws ClassNotFoundException {
+
+ Class<?> clazz = null;
+ try {
+
+ if (this.getParent() != null)
+ clazz = this.getParent().loadClass(className);
+
+ } catch (ClassNotFoundException e) {
+ }
+
+ if (clazz == null)
+ clazz = findClass(className);
+
+
+ if (resolveClass)
+ this.resolveClass(clazz);
+ return clazz;
+
+ }
+
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.net.URLClassLoader#findResource(java.lang.String)
+ */
+ @Override
+ public URL findResource(String name) {
+
+ URL url = findResourceFromContribution(name);
+
+ if (url == null) {
+ for (Import import_ : this.contribution.getImports()) {
+ if (matchesImport(name, import_, false)) {
+ // Delegate the resolution to the imported contribution
+ for (Contribution exportingContribution : import_.getExportContributions()) {
+
+ if (exportingContribution.getClassLoader() instanceof ContributionClassLoader) {
+
+ for (Export export : exportingContribution.getExports()) {
+ if (import_.match(export)) {
+ url = ((ContributionClassLoader)exportingContribution.getClassLoader()).findResourceFromContribution(name);
+ if (url != null) break;
+ }
+ }
+ if (url != null) break;
+ }
+ }
+ if (url != null) break;
+ }
+ }
+
+ }
+ return url;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.net.URLClassLoader#findResources(java.lang.String)
+ */
+ @Override
+ public Enumeration<URL> findResources(String name) throws IOException {
+
+ return collectionToEnumeration(findResourceSet(name));
+ }
+
+
+
+
+ /* (non-Javadoc)
+ * @see java.lang.ClassLoader#getResource(java.lang.String)
+ *
+ * Find a resource.
+ * Search path for resource:
+ * Parent classloader
+ * This contribution
+ * Imported contributions
+ */
+ @Override
+ public URL getResource(String resName) {
+
+ URL resource = null;
+
+ if (this.getParent() != null) {
+ resource = this.getParent().getResource(resName);
+ }
+ if (resource == null)
+ resource = findResource(resName);
+
+ return resource;
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see java.lang.ClassLoader#getResources(java.lang.String)
+ *
+ * Return list of resources from this contribution, resources
+ * imported through imported contributions and resources from parent
+ * classloader.
+ */
+ @Override
+ public Enumeration<URL> getResources(String resName) throws IOException {
+
+ HashSet<URL> resourceSet = findResourceSet(resName);
+ addEnumerationToCollection(resourceSet, super.getResources(resName));
+
+ return collectionToEnumeration(resourceSet);
+ }
+
+
+ /*
+ * Find set of resources
+ */
+ private HashSet<URL> findResourceSet(String name) throws IOException {
+
+ HashSet<URL> resources = new HashSet<URL>();
+
+ addEnumerationToCollection(resources, super.findResources(name));
+
+ for (Import import_ : this.contribution.getImports()) {
+ if (matchesImport(name, import_, false)) {
+ // Delegate the resolution to the imported contribution
+ for (Contribution exportingContribution : import_.getExportContributions()) {
+
+ if (exportingContribution.getClassLoader() instanceof ContributionClassLoader) {
+
+ for (Export export : exportingContribution.getExports()) {
+ if (import_.match(export)) {
+ addEnumerationToCollection(resources,
+ ((ContributionClassLoader)exportingContribution.getClassLoader()).findResources(name));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return resources;
+ }
+
+
+ /*
+ * Find class from contribution. If class has already been loaded, return loaded class.
+ */
+ private Class<?> findClassFromContribution(String className) throws ClassNotFoundException {
+
+ Class<?> clazz = findLoadedClass(className);
+ if (clazz == null)
+ clazz = super.findClass(className);
+ return clazz;
+
+ }
+
+ /*
+ * Find resource from contribution.
+ */
+ private URL findResourceFromContribution(String name) {
+
+ return super.findResource(name);
+ }
+
+ /**
+ * Check if a class or resource matches an import statement.
+ * Class matches if the package name used in <import.java/> matches
+ * Resource matches if package/namespace match the directory of resource.
+ *
+ * @param name Name of class or resource
+ * @param import_ SCA contribution import
+ * @param matchJavaClass
+ * @return true if this is a matching import
+ */
+ private boolean matchesImport(String name, Import import_, boolean matchJavaClass) {
+
+ if (matchJavaClass) {
+ if (import_ instanceof JavaImport && name != null && name.lastIndexOf('.') > 0) {
+ JavaImport javaImport = (JavaImport) import_;
+ String packageName = name.substring(0, name.lastIndexOf('.'));
+ if (javaImport.getPackage() == null)
+ return false;
+ else
+ return packageName.equals(javaImport.getPackage());
+ }
+
+ } else {
+ if (name == null || name.lastIndexOf('/') <= 0)
+ return false;
+ else if (import_ instanceof JavaImport) {
+ JavaImport javaImport = (JavaImport) import_;
+ String packageName = name.substring(0, name.lastIndexOf('/'));
+ if (javaImport.getPackage() == null)
+ return false;
+ else
+ return packageName.equals(javaImport.getPackage().replaceAll("\\.", "/"));
+ } else if (import_ instanceof NamespaceImport) {
+ NamespaceImport namespaceImport = (NamespaceImport) import_;
+ String namespace = name.substring(0, name.lastIndexOf('/'));
+ if (namespaceImport.getNamespace() == null)
+ return false;
+ else
+ return namespaceImport.getNamespace().equals(namespace);
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Add an enumeration to a Collection
+ */
+ private <T extends Object> void addEnumerationToCollection(Collection<T> collection, Enumeration<T> enumeration) {
+
+ while (enumeration.hasMoreElements())
+ collection.add(enumeration.nextElement());
+ }
+
+ /*
+ * Return an enumeration corresponding to a collection
+ */
+ private <T extends Object> Enumeration<T> collectionToEnumeration(Collection<T> collection) {
+
+ final Iterator<T> iterator = collection.iterator();
+
+ return new Enumeration<T>() {
+ public boolean hasMoreElements() {
+ return iterator.hasNext();
+ }
+
+ public T nextElement() {
+ return iterator.next();
+ }
+ };
+ }
+
+
+ @Override
+ public String toString() {
+ return "SCA contribution classloader for : " + contribution.getLocation();
+ }
+
+
+}
Propchange: incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoader.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java (original)
+++ incubator/tuscany/java/sca/modules/contribution-impl/src/main/java/org/apache/tuscany/sca/contribution/impl/ContributionImpl.java Fri Oct 26 06:52:36 2007
@@ -39,6 +39,7 @@
private List<Import> imports = new ArrayList<Import>();
private List<Composite> deployables = new ArrayList<Composite>();
private ModelResolver modelResolver;
+ private ContributionClassLoader classLoader;
/**
* A list of artifacts in the contribution
@@ -46,6 +47,7 @@
private List<DeployedArtifact> artifacts = new ArrayList<DeployedArtifact>();
protected ContributionImpl() {
+ classLoader = new ContributionClassLoader(this);
}
public List<Export> getExports() {
@@ -71,4 +73,21 @@
public void setModelResolver(ModelResolver modelResolver) {
this.modelResolver = modelResolver;
}
+
+
+
+ @Override
+ public void setLocation(String location) {
+ String origLocation = this.getLocation();
+ super.setLocation(location);
+
+ if (origLocation != null)
+ classLoader = new ContributionClassLoader(this);
+ classLoader.setContributionLocation(location);
+ }
+
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
}
Added: incubator/tuscany/java/sca/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoaderTestCase.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoaderTestCase.java?rev=588644&view=auto
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoaderTestCase.java (added)
+++ incubator/tuscany/java/sca/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoaderTestCase.java Fri Oct 26 06:52:36 2007
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.impl;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.impl.ContributionFactoryImpl;
+import org.apache.tuscany.sca.contribution.java.JavaExport;
+import org.apache.tuscany.sca.contribution.java.JavaImport;
+import org.apache.tuscany.sca.contribution.java.JavaImportExportFactory;
+import org.apache.tuscany.sca.contribution.java.impl.JavaImportExportFactoryImpl;
+import org.apache.tuscany.sca.contribution.namespace.NamespaceExport;
+import org.apache.tuscany.sca.contribution.namespace.NamespaceImport;
+import org.apache.tuscany.sca.contribution.namespace.NamespaceImportExportFactory;
+import org.apache.tuscany.sca.contribution.namespace.impl.NamespaceImportExportFactoryImpl;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * Test ContributionClassLoader.
+ *
+ */
+public class ContributionClassLoaderTestCase {
+
+ private ContributionFactory contribFactory;
+ private JavaImportExportFactory javaImportExportFactory;
+ private NamespaceImportExportFactory namespaceImportExportFactory;
+
+ @Before
+ public void setUp() throws Exception {
+ contribFactory = new ContributionFactoryImpl();
+ javaImportExportFactory = new JavaImportExportFactoryImpl();
+ namespaceImportExportFactory = new NamespaceImportExportFactoryImpl();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ private Contribution createContribution(String fileName) throws MalformedURLException {
+
+ Contribution contrib = contribFactory.createContribution();
+ File contribDir = new File(fileName);
+ contrib.setLocation(contribDir.toURL().toString());
+
+ return contrib;
+ }
+
+
+ @Test
+ public void testClassLoadingFromContribution() throws ClassNotFoundException, MalformedURLException {
+
+ Contribution contribA = createContribution("target/test-classes");
+ Contribution contribB = createContribution("target");
+ Contribution contribC = createContribution("target/test-classes/deployables/sample-calculator.jar");
+
+ // Class present in contribution, also in parent. Class is loaded from parent
+ Class<?> testClassA = contribA.getClassLoader().loadClass(this.getClass().getName());
+ Assert.assertNotNull(testClassA);
+ Assert.assertSame(this.getClass(), testClassA);
+
+ // Class not present in contribution, but present in parent classloader
+ Class<?> testClassB = contribB.getClassLoader().loadClass(this.getClass().getName());
+ Assert.assertNotNull(testClassB);
+ Assert.assertSame(this.getClass(), testClassB);
+
+ // Class present in contribution, but not in parent
+ Class<?> testClassC = contribC.getClassLoader().loadClass("calculator.AddService");
+ Assert.assertNotNull(testClassC);
+
+ // Class not present in contribution or in parent
+ try {
+ contribA.getClassLoader().loadClass("NonExistent");
+
+ Assert.assertTrue("ClassNotFoundException not thrown as expected", false);
+
+ } catch (ClassNotFoundException e) {
+ }
+
+
+
+ }
+
+ @Test
+ public void testResourceLoadingFromContribution() throws ClassNotFoundException, MalformedURLException {
+
+ Contribution contribA = createContribution("target/test-classes");
+ Contribution contribB = createContribution("target");
+ Contribution contribC = createContribution("target/test-classes/deployables/sample-calculator.jar");
+
+ // Resource present in contribution, and in parent
+ URL resA = contribA.getClassLoader().getResource("deployables/sample-calculator.jar");
+ Assert.assertNotNull(resA);
+
+ // Resource not present in contribution, but present in parent classloader
+ URL resB = contribB.getClassLoader().getResource("deployables/sample-calculator.jar");
+ Assert.assertNotNull(resB);
+
+ // Resource present in contribution, but not in parent
+ URL resC = contribC.getClassLoader().getResource("calculator/AddService.class");
+ Assert.assertNotNull(resC);
+
+ // Load Java class as resource from parent
+ String classResName = this.getClass().getName().replaceAll("\\.", "/") + ".class";
+ URL classResA = contribA.getClassLoader().getResource(classResName);
+ Assert.assertNotNull(classResA);
+
+ // Non-existent resource
+ URL res = contribA.getClassLoader().getResource("deployables/NonExistent");
+ Assert.assertNull(res);
+
+ }
+
+
+ @Test
+ public void testClassLoadingFromImportedContribution() throws ClassNotFoundException, MalformedURLException {
+
+ Contribution contribA = createContribution("target/test-classes");
+ Contribution contribB = createContribution("target");
+ Contribution contribC = createContribution("target/test-classes/deployables/sample-calculator.jar");
+ ArrayList<Contribution> exportContribList = new ArrayList<Contribution>();
+ exportContribList.add(contribA);
+ exportContribList.add(contribC);
+
+ JavaImport import_ = javaImportExportFactory.createJavaImport();
+ import_.setPackage(this.getClass().getPackage().getName());
+ import_.setExportContributions(exportContribList);
+ contribB.getImports().add(import_);
+ import_ = javaImportExportFactory.createJavaImport();
+ import_.setPackage("calculator");
+ import_.setExportContributions(exportContribList);
+ contribB.getImports().add(import_);
+
+ JavaExport export = javaImportExportFactory.createJavaExport();
+ export.setPackage(this.getClass().getPackage().getName());
+ contribA.getExports().add(export);
+ export = javaImportExportFactory.createJavaExport();
+ export.setPackage("calculator");
+ contribC.getExports().add(export);
+
+ // Load class from parent, class is also present in imported contribution. Class should
+ // be loaded from parent
+ Class<?> testClassB = contribB.getClassLoader().loadClass(this.getClass().getName());
+ Assert.assertNotNull(testClassB);
+ Assert.assertSame(this.getClass(), testClassB);
+
+ // Load class from parent, class is also present in parent. Class should be loaded
+ // from parent.
+ Class<?> testClassA = contribA.getClassLoader().loadClass(this.getClass().getName());
+ Assert.assertNotNull(testClassA);
+ Assert.assertSame(this.getClass(), testClassA);
+
+ // Imported class should be the same as the one loaded by the exporting contribution
+ Assert.assertSame(testClassA, testClassB);
+
+ // Load class from imported contribution, class is not present in parent
+ Class<?> testClassB1 = contribB.getClassLoader().loadClass("calculator.AddService");
+ Assert.assertNotNull(testClassB1);
+
+ // Imported class should be the same as the one loaded by the exporting contribution
+ Class<?> testClassC = contribC.getClassLoader().loadClass("calculator.AddService");
+ Assert.assertNotNull(testClassC);
+ Assert.assertSame(testClassC, testClassB1);
+
+
+ // Try to load class from package which is not explicitly imported - should throw ClassNotFoundException
+ try {
+ contribA.getClassLoader().loadClass("calculator.AddService");
+
+ Assert.assertTrue("ClassNotFoundException not thrown as expected", false);
+
+ } catch (ClassNotFoundException e) {
+ }
+
+ // Try to load non-existent class from imported package - should throw ClassNotFoundException
+ try {
+ contribB.getClassLoader().loadClass(this.getClass().getPackage().getName() + ".NonExistentClass");
+
+ Assert.assertTrue("ClassNotFoundException not thrown as expected", false);
+
+ } catch (ClassNotFoundException e) {
+ }
+
+ }
+
+ @Test
+ public void testResourceLoadingFromImportedContribution() throws ClassNotFoundException, MalformedURLException {
+
+ Contribution contribA = createContribution("target/test-classes");
+ Contribution contribB = createContribution("target");
+ Contribution contribC = createContribution("target/test-classes/deployables/sample-calculator.jar");
+
+ ArrayList<Contribution> exportContribList = new ArrayList<Contribution>();
+ exportContribList.add(contribA);
+ exportContribList.add(contribC);
+
+ JavaImport import_ = javaImportExportFactory.createJavaImport();
+ import_.setPackage(this.getClass().getPackage().getName());
+ import_.setExportContributions(exportContribList);
+ contribB.getImports().add(import_);
+ NamespaceImport import1_ = namespaceImportExportFactory.createNamespaceImport();
+ import1_.setNamespace("calculator");
+ import1_.setExportContributions(exportContribList);
+ contribB.getImports().add(import1_);
+
+ JavaExport export = javaImportExportFactory.createJavaExport();
+ export.setPackage(this.getClass().getPackage().getName());
+ contribA.getExports().add(export);
+ NamespaceExport export1 = namespaceImportExportFactory.createNamespaceExport();
+ export1.setNamespace("calculator");
+ contribC.getExports().add(export1);
+
+ // Load resource from parent
+ URL resB = contribB.getClassLoader().getResource("deployables/sample-calculator.jar");
+ Assert.assertNotNull(resB);
+
+ // Load Java class as resource from imported contribution with JavaImport
+ String classResName = this.getClass().getName().replaceAll("\\.", "/") + ".class";
+ URL classResB = contribB.getClassLoader().getResource(classResName);
+ Assert.assertNotNull(classResB);
+
+ // Load Java class as resource from imported contribution with NamespaceImport
+ URL classResB1 = contribB.getClassLoader().getResource("calculator/AddService.class");
+ Assert.assertNotNull(classResB1);
+
+ // Try to load resource not explicitly imported by contribution
+ URL classResA1 = contribA.getClassLoader().getResource("calculator/AddService.class");
+ Assert.assertNull(classResA1);
+
+
+ }
+
+}
Propchange: incubator/tuscany/java/sca/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoaderTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/tuscany/java/sca/modules/contribution-impl/src/test/java/org/apache/tuscany/sca/contribution/impl/ContributionClassLoaderTestCase.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceModelResolver.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceModelResolver.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceModelResolver.java (original)
+++ incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/ClassReferenceModelResolver.java Fri Oct 26 06:52:36 2007
@@ -25,9 +25,7 @@
import java.util.Map;
import org.apache.tuscany.sca.contribution.Contribution;
-import org.apache.tuscany.sca.contribution.Import;
import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
-import org.apache.tuscany.sca.contribution.java.JavaImport;
import org.apache.tuscany.sca.contribution.resolver.ClassReference;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
@@ -45,8 +43,12 @@
public ClassReferenceModelResolver(Contribution contribution, ModelFactoryExtensionPoint modelFactories) {
this.contribution = contribution;
- //FIXME The classloader should be passed in
- this.classLoader = new WeakReference<ClassLoader>(Thread.currentThread().getContextClassLoader());
+ if (this.contribution != null) {
+ this.classLoader = new WeakReference<ClassLoader>(this.contribution.getClassLoader());
+ } else {
+ // This path should be used only for unit testing.
+ this.classLoader = new WeakReference<ClassLoader>(this.getClass().getClassLoader());
+ }
try {
Class osgiResolverClass =
@@ -69,29 +71,7 @@
return map.remove(((ClassReference)resolved).getClassName());
}
- /**
- * Handle artifact resolution when the specific class reference is imported from another contribution
- * @param unresolved
- * @return
- */
- private ClassReference resolveImportedModel(ClassReference unresolved) {
- ClassReference resolved = unresolved;
-
- if (this.contribution != null) {
- for (Import import_ : this.contribution.getImports()) {
- if (import_ instanceof JavaImport) {
- JavaImport javaImport = (JavaImport)import_;
- String packageName = javaImport.getPackage();
- if (javaImport.getPackage().equals(packageName)) {
- // Delegate the resolution to the import resolver
- resolved = import_.getModelResolver().resolveModel(ClassReference.class, unresolved);
- }
- }
- }
-
- }
- return resolved;
- }
+
public <T> T resolveModel(Class<T> modelClass, T unresolved) {
Object resolved = map.get(unresolved);
@@ -122,9 +102,7 @@
// Return the resolved ClassReference
return modelClass.cast(classReference);
} else {
- //delegate resolution of the class
- resolved = this.resolveImportedModel((ClassReference)unresolved);
- return modelClass.cast(resolved);
+ return unresolved;
}
}
Modified: incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportImpl.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportImpl.java (original)
+++ incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaExportImpl.java Fri Oct 26 06:52:36 2007
@@ -19,6 +19,7 @@
package org.apache.tuscany.sca.contribution.java.impl;
+import org.apache.tuscany.sca.contribution.Contribution;
import org.apache.tuscany.sca.contribution.java.JavaExport;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
@@ -29,6 +30,7 @@
*/
public class JavaExportImpl implements JavaExport {
private ModelResolver modelResolver;
+ private Contribution contribution;
/**
* Java package being exported
*/
@@ -54,4 +56,11 @@
this.modelResolver = modelResolver;
}
+ public Contribution getContribution() {
+ return contribution;
+ }
+
+ public void setContribution(Contribution contribution) {
+ this.contribution = contribution;
+ }
}
Modified: incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportListener.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportListener.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportListener.java (original)
+++ incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportExportListener.java Fri Oct 26 06:52:36 2007
@@ -19,6 +19,9 @@
package org.apache.tuscany.sca.contribution.java.impl;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.tuscany.sca.contribution.Contribution;
import org.apache.tuscany.sca.contribution.Export;
import org.apache.tuscany.sca.contribution.Import;
@@ -42,16 +45,20 @@
* Export model resolvers are same as Contribution model resolver
* Import model resolvers are matched to a specific contribution if a location uri is specified,
* otherwise it try to resolve agains all the other contributions
+ * Also set the exporting contributions used by contribution classloaders to
+ * match import/export for class loading.
*/
public void contributionAdded(ContributionRepository repository, Contribution contribution) {
// Initialize the contribution exports
for (Export export: contribution.getExports()) {
export.setModelResolver(contribution.getModelResolver());
+ export.setContribution(contribution);
}
// Initialize the contribution imports
for (Import import_: contribution.getImports()) {
boolean initialized = false;
+
if(import_ instanceof JavaImport) {
JavaImport javaImport = (JavaImport) import_;
@@ -66,6 +73,11 @@
JavaExport javaExport = (JavaExport)export;
if (javaImport.getPackage().equals(javaExport.getPackage())) {
javaImport.setModelResolver(javaExport.getModelResolver());
+
+ List<Contribution> exportingContributions = new ArrayList<Contribution>();
+ exportingContributions.add(export.getContribution());
+ import_.setExportContributions(exportingContributions);
+
initialized = true;
break;
}
@@ -78,6 +90,7 @@
if (!initialized) {
//Use a resolver that will consider all contributions
import_.setModelResolver(new DefaultImportAllModelResolver(import_, repository.getContributions()));
+ import_.setExportContributions(repository.getContributions());
}
}
}
Modified: incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportImpl.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportImpl.java (original)
+++ incubator/tuscany/java/sca/modules/contribution-java/src/main/java/org/apache/tuscany/sca/contribution/java/impl/JavaImportImpl.java Fri Oct 26 06:52:36 2007
@@ -19,6 +19,9 @@
package org.apache.tuscany.sca.contribution.java.impl;
+import java.util.List;
+
+import org.apache.tuscany.sca.contribution.Contribution;
import org.apache.tuscany.sca.contribution.Export;
import org.apache.tuscany.sca.contribution.java.JavaExport;
import org.apache.tuscany.sca.contribution.java.JavaImport;
@@ -31,6 +34,7 @@
*/
public class JavaImportImpl implements JavaImport {
private ModelResolver modelResolver;
+ private List<Contribution> contributions;
/**
* Java package name being imported
*/
@@ -66,6 +70,13 @@
public void setModelResolver(ModelResolver modelResolver) {
this.modelResolver = modelResolver;
+ }
+ public List<Contribution> getExportContributions() {
+ return contributions;
+ }
+
+ public void setExportContributions(List<Contribution> contributions) {
+ this.contributions = contributions;
}
/**
Modified: incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportImpl.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportImpl.java (original)
+++ incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceExportImpl.java Fri Oct 26 06:52:36 2007
@@ -19,6 +19,7 @@
package org.apache.tuscany.sca.contribution.namespace.impl;
+import org.apache.tuscany.sca.contribution.Contribution;
import org.apache.tuscany.sca.contribution.namespace.NamespaceExport;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
@@ -33,6 +34,7 @@
*/
private String namespace;
private ModelResolver modelResolver;
+ private Contribution contribution;
protected NamespaceExportImpl() {
super();
@@ -52,5 +54,13 @@
public void setModelResolver(ModelResolver modelResolver) {
this.modelResolver = modelResolver;
+ }
+
+ public Contribution getContribution() {
+ return contribution;
+ }
+
+ public void setContribution(Contribution contribution) {
+ this.contribution = contribution;
}
}
Modified: incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportListener.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportListener.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportListener.java (original)
+++ incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportExportListener.java Fri Oct 26 06:52:36 2007
@@ -19,6 +19,9 @@
package org.apache.tuscany.sca.contribution.namespace.impl;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.tuscany.sca.contribution.Contribution;
import org.apache.tuscany.sca.contribution.Export;
import org.apache.tuscany.sca.contribution.Import;
@@ -42,16 +45,20 @@
* Export model resolvers are same as Contribution model resolver
* Import model resolvers are matched to a specific contribution if a location uri is specified,
* otherwise it try to resolve agains all the other contributions
+ * Also set the exporting contributions used by contribution classloaders to
+ * match import/export for class loading.
*/
public void contributionAdded(ContributionRepository repository, Contribution contribution) {
// Initialize the contribution exports
for (Export export: contribution.getExports()) {
export.setModelResolver(contribution.getModelResolver());
+ export.setContribution(contribution);
}
// Initialize the contribution imports
for (Import import_: contribution.getImports()) {
boolean initialized = false;
+
if (import_ instanceof NamespaceImport) {
NamespaceImport namespaceImport = (NamespaceImport)import_;
@@ -67,6 +74,11 @@
NamespaceExport namespaceExport = (NamespaceExport)export;
if (namespaceImport.getNamespace().equals(namespaceExport.getNamespace())) {
namespaceImport.setModelResolver(namespaceExport.getModelResolver());
+
+ List<Contribution> exportingContributions = new ArrayList<Contribution>();
+ exportingContributions.add(namespaceExport.getContribution());
+ import_.setExportContributions(exportingContributions);
+
initialized = true;
break;
}
@@ -80,8 +92,8 @@
if( !initialized ) {
// Use a resolver that will consider all contributions
import_.setModelResolver(new DefaultImportAllModelResolver(import_, repository.getContributions()));
+ import_.setExportContributions(repository.getContributions());
}
-
}
}
Modified: incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportImpl.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportImpl.java (original)
+++ incubator/tuscany/java/sca/modules/contribution-namespace/src/main/java/org/apache/tuscany/sca/contribution/namespace/impl/NamespaceImportImpl.java Fri Oct 26 06:52:36 2007
@@ -19,6 +19,9 @@
package org.apache.tuscany.sca.contribution.namespace.impl;
+import java.util.List;
+
+import org.apache.tuscany.sca.contribution.Contribution;
import org.apache.tuscany.sca.contribution.Export;
import org.apache.tuscany.sca.contribution.namespace.NamespaceExport;
import org.apache.tuscany.sca.contribution.namespace.NamespaceImport;
@@ -31,6 +34,7 @@
*/
public class NamespaceImportImpl implements NamespaceImport {
private ModelResolver modelResolver;
+ private List<Contribution> exportContributions;
/**
* The namespace to be imported
*/
@@ -67,6 +71,15 @@
public void setModelResolver(ModelResolver modelResolver) {
this.modelResolver = modelResolver;
+ }
+
+
+ public List<Contribution> getExportContributions() {
+ return exportContributions;
+ }
+
+ public void setExportContributions(List<Contribution> contributions) {
+ this.exportContributions = contributions;
}
/**
Modified: incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java (original)
+++ incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Contribution.java Fri Oct 26 06:52:36 2007
@@ -88,4 +88,13 @@
*/
void setModelResolver(ModelResolver modelResolver);
+ /**
+ * Returns the classloader used to load classes and resources from
+ * this contribution
+ *
+ * @return The contribution classloader
+ */
+ ClassLoader getClassLoader();
+
+
}
Modified: incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java (original)
+++ incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Export.java Fri Oct 26 06:52:36 2007
@@ -44,4 +44,19 @@
*/
void setModelResolver(ModelResolver modelResolver);
+
+ /**
+ * Returns the exporting contribution
+ *
+ * @return The exporting contribution
+ */
+ Contribution getContribution();
+
+ /**
+ * Sets the exporting contribution
+ *
+ * @param contribution
+ */
+ void setContribution(Contribution contribution);
+
}
Modified: incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java (original)
+++ incubator/tuscany/java/sca/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/Import.java Fri Oct 26 06:52:36 2007
@@ -19,6 +19,8 @@
package org.apache.tuscany.sca.contribution;
+import java.util.List;
+
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
@@ -44,6 +46,22 @@
* @param modelResolver The model resolver
*/
void setModelResolver(ModelResolver modelResolver);
+
+ /**
+ * Returns the list of exporting contributions that can be used to match
+ * this import.
+ *
+ * @return List of exporting contributions
+ */
+ List<Contribution> getExportContributions();
+
+ /**
+ * Sets the list of exporting contributions that can be used to match
+ * this import.
+ *
+ * @param contributions List of exporting contributions
+ */
+ void setExportContributions(List<Contribution> contributions);
/**
* Verify is a specific export is provider of what is being imported
Modified: incubator/tuscany/java/sca/modules/pom.xml
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/pom.xml?rev=588644&r1=588643&r2=588644&view=diff
==============================================================================
--- incubator/tuscany/java/sca/modules/pom.xml (original)
+++ incubator/tuscany/java/sca/modules/pom.xml Fri Oct 26 06:52:36 2007
@@ -58,9 +58,9 @@
<module>binding-ws-axis2</module>
<module>binding-ws-xml</module>
<module>contribution</module>
- <module>contribution-impl</module>
<module>contribution-namespace</module>
<module>contribution-java</module>
+ <module>contribution-impl</module>
<module>contribution-osgi</module>
<module>core</module>
<module>core-databinding</module>
---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-commits-help@ws.apache.org