You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by rf...@apache.org on 2007/02/07 01:48:22 UTC
svn commit: r504392 -
/incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java
Author: rfeng
Date: Tue Feb 6 16:48:21 2007
New Revision: 504392
URL: http://svn.apache.org/viewvc?view=rev&rev=504392
Log:
Copy the MultiParentClassLoader from Axis2
Added:
incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java (with props)
Added: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java?view=auto&rev=504392
==============================================================================
--- incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java (added)
+++ incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java Tue Feb 6 16:48:21 2007
@@ -0,0 +1,402 @@
+/*
+ * 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.spi.util;
+
+import java.beans.Introspector;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A MultiParentClassLoader is a simple extension of the URLClassLoader that
+ * simply changes the single parent class loader model to support a list of
+ * parent class loaders. Each operation that accesses a parent, has been
+ * replaced with a operation that checks each parent in order. This getParent
+ * method of this class will always return null, which may be interpreted by the
+ * calling code to mean that this class loader is a direct child of the system
+ * class loader.
+ *
+ * @version $Rev$ $Date$
+ */
+public class MultiParentClassLoader extends URLClassLoader {
+ private boolean destroyed;
+ private final String[] hiddenClasses;
+ private final String[] hiddenResources;
+ private final boolean inverseClassLoading;
+ private final String[] nonOverridableClasses;
+ private final String[] nonOverridableResources;
+
+ private final ClassLoader[] parents;
+
+ /**
+ * Creates a named class loader with no parents.
+ *
+ * @param urls the urls from which this class loader will classes and
+ * resources
+ */
+ public MultiParentClassLoader(URL[] urls) {
+ super(urls);
+ parents = new ClassLoader[] {ClassLoader.getSystemClassLoader()};
+ inverseClassLoading = false;
+ hiddenClasses = new String[0];
+ nonOverridableClasses = new String[0];
+ hiddenResources = new String[0];
+ nonOverridableResources = new String[0];
+ }
+
+ /**
+ * Creates a named class loader as a child of the specified parent.
+ *
+ * @param urls the urls from which this class loader will classes and
+ * resources
+ * @param parent the parent of this class loader
+ */
+ public MultiParentClassLoader(URL[] urls, ClassLoader parent) {
+ this(urls, new ClassLoader[] {parent});
+ }
+
+ public MultiParentClassLoader(URL[] urls,
+ ClassLoader parent,
+ boolean inverseClassLoading,
+ String[] hiddenClasses,
+ String[] nonOverridableClasses) {
+ this(urls, new ClassLoader[] {parent}, inverseClassLoading, hiddenClasses, nonOverridableClasses);
+ }
+
+ /**
+ * Creates a named class loader as a child of the specified parent and using
+ * the specified URLStreamHandlerFactory for accessing the urls..
+ *
+ * @param urls the urls from which this class loader will classes and
+ * resources
+ * @param parent the parent of this class loader
+ * @param factory the URLStreamHandlerFactory used to access the urls
+ */
+ public MultiParentClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) {
+ this(urls, new ClassLoader[] {parent}, factory);
+ }
+
+ /**
+ * Creates a named class loader as a child of the specified parents.
+ *
+ * @param urls the urls from which this class loader will classes and
+ * resources
+ * @param parents the parents of this class loader
+ */
+ public MultiParentClassLoader(URL[] urls, ClassLoader[] parents) {
+ super(urls);
+ this.parents = copyParents(parents);
+ inverseClassLoading = false;
+ hiddenClasses = new String[0];
+ nonOverridableClasses = new String[0];
+ hiddenResources = new String[0];
+ nonOverridableResources = new String[0];
+ }
+
+ public MultiParentClassLoader(URL[] urls,
+ ClassLoader[] parents,
+ boolean inverseClassLoading,
+ Collection<String> hiddenClasses,
+ Collection<String> nonOverridableClasses) {
+ this(urls, parents, inverseClassLoading, (String[])hiddenClasses.toArray(new String[hiddenClasses.size()]),
+ (String[])nonOverridableClasses.toArray(new String[nonOverridableClasses.size()]));
+ }
+
+ public MultiParentClassLoader(URL[] urls,
+ ClassLoader[] parents,
+ boolean inverseClassLoading,
+ String[] hiddenClasses,
+ String[] nonOverridableClasses) {
+ super(urls);
+ this.parents = copyParents(parents);
+ this.inverseClassLoading = inverseClassLoading;
+ this.hiddenClasses = hiddenClasses;
+ this.nonOverridableClasses = nonOverridableClasses;
+ hiddenResources = toResources(hiddenClasses);
+ nonOverridableResources = toResources(nonOverridableClasses);
+ }
+
+ /**
+ * Creates a named class loader as a child of the specified parents and
+ * using the specified URLStreamHandlerFactory for accessing the urls..
+ *
+ * @param urls the urls from which this class loader will classes and
+ * resources
+ * @param parents the parents of this class loader
+ * @param factory the URLStreamHandlerFactory used to access the urls
+ */
+ public MultiParentClassLoader(URL[] urls, ClassLoader[] parents, URLStreamHandlerFactory factory) {
+ super(urls, null, factory);
+ this.parents = copyParents(parents);
+ inverseClassLoading = false;
+ hiddenClasses = new String[0];
+ nonOverridableClasses = new String[0];
+ hiddenResources = new String[0];
+ nonOverridableResources = new String[0];
+ }
+
+ private static ClassLoader[] copyParents(ClassLoader[] parents) {
+ ClassLoader[] newParentsArray = new ClassLoader[parents.length];
+ for (int i = 0; i < parents.length; i++) {
+ ClassLoader parent = parents[i];
+ if (parent == null) {
+ throw new RuntimeException("parent[" + i + "] is null");
+ }
+ newParentsArray[i] = parent;
+ }
+ return newParentsArray;
+ }
+
+ public void addURL(URL url) {
+ // todo this needs a security check
+ super.addURL(url);
+ }
+
+ public void destroy() {
+ synchronized (this) {
+ if (destroyed) {
+ return;
+ }
+ destroyed = true;
+ }
+
+ // clearSoftCache(ObjectInputStream.class, "subclassAudits");
+ // clearSoftCache(ObjectOutputStream.class, "subclassAudits");
+ // clearSoftCache(ObjectStreamClass.class, "localDescs");
+ // clearSoftCache(ObjectStreamClass.class, "reflectors");
+
+ // The beanInfoCache in java.beans.Introspector will hold on to Classes
+ // which
+ // it has introspected. If we don't flush the cache, we may run out of
+ // Permanent Generation space.
+ Introspector.flushCaches();
+ }
+
+ public Enumeration<URL> findResources(String name) throws IOException {
+ if (isDestroyed()) {
+ Set<URL> emptySet = Collections.emptySet();
+ return Collections.enumeration(emptySet);
+ }
+
+ List<URL> resources = new ArrayList<URL>();
+
+ //
+ // if we are using inverse class loading, add the resources from local
+ // urls first
+ //
+ if (inverseClassLoading && !isDestroyed()) {
+ List<URL> myResources = Collections.list(super.findResources(name));
+ resources.addAll(myResources);
+ }
+
+ //
+ // Add parent resources
+ //
+ for (int i = 0; i < parents.length; i++) {
+ ClassLoader parent = parents[i];
+ List<URL> parentResources = Collections.list(parent.getResources(name));
+ resources.addAll(parentResources);
+ }
+
+ //
+ // if we are not using inverse class loading, add the resources from
+ // local urls now
+ //
+ if (!inverseClassLoading && !isDestroyed()) {
+ List<URL> myResources = Collections.list(super.findResources(name));
+ resources.addAll(myResources);
+ }
+
+ return Collections.enumeration(resources);
+ }
+
+ /**
+ * Gets the parents of this class loader.
+ *
+ * @return the parents of this class loader
+ */
+ public ClassLoader[] getParents() {
+ return parents;
+ }
+
+ public URL getResource(String name) {
+ if (isDestroyed()) {
+ return null;
+ }
+
+ //
+ // if we are using inverse class loading, check local urls first
+ //
+ if (inverseClassLoading && !isDestroyed() && !isNonOverridableResource(name)) {
+ URL url = findResource(name);
+ if (url != null) {
+ return url;
+ }
+ }
+
+ //
+ // Check parent class loaders
+ //
+ if (!isHiddenResource(name)) {
+ for (int i = 0; i < parents.length; i++) {
+ ClassLoader parent = parents[i];
+ URL url = parent.getResource(name);
+ if (url != null) {
+ return url;
+ }
+ }
+ }
+
+ //
+ // if we are not using inverse class loading, check local urls now
+ //
+ // don't worry about excluding non-overridable resources here... we
+ // have alredy checked he parent and the parent didn't have the
+ // resource, so we can override now
+ if (!isDestroyed()) {
+ // parents didn't have the resource; attempt to load it from my urls
+ return findResource(name);
+ }
+
+ return null;
+ }
+
+ public synchronized boolean isDestroyed() {
+ return destroyed;
+ }
+
+ private boolean isHiddenClass(String name) {
+ for (int i = 0; i < hiddenClasses.length; i++) {
+ if (name.startsWith(hiddenClasses[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isHiddenResource(String name) {
+ for (int i = 0; i < hiddenResources.length; i++) {
+ if (name.startsWith(hiddenResources[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isNonOverridableClass(String name) {
+ for (int i = 0; i < nonOverridableClasses.length; i++) {
+ if (name.startsWith(nonOverridableClasses[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isNonOverridableResource(String name) {
+ for (int i = 0; i < nonOverridableResources.length; i++) {
+ if (name.startsWith(nonOverridableResources[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ //
+ // Check if class is in the loaded classes cache
+ //
+ Class cachedClass = findLoadedClass(name);
+ if (cachedClass != null) {
+ return resolveClass(cachedClass, resolve);
+ }
+
+ //
+ // if we are using inverse class loading, check local urls first
+ //
+ if (inverseClassLoading && !isDestroyed() && !isNonOverridableClass(name)) {
+ try {
+ Class clazz = findClass(name);
+ return resolveClass(clazz, resolve);
+ } catch (ClassNotFoundException ignored) {
+ // Ignore it
+ }
+ }
+
+ //
+ // Check parent class loaders
+ //
+ if (!isHiddenClass(name)) {
+ for (int i = 0; i < parents.length; i++) {
+ ClassLoader parent = parents[i];
+ try {
+ Class clazz = parent.loadClass(name);
+ return resolveClass(clazz, resolve);
+ } catch (ClassNotFoundException ignored) {
+ // this parent didn't have the class; try the next one
+ }
+ }
+ }
+
+ //
+ // if we are not using inverse class loading, check local urls now
+ //
+ // don't worry about excluding non-overridable classes here... we
+ // have alredy checked he parent and the parent didn't have the
+ // class, so we can override now
+ if (!isDestroyed()) {
+ try {
+ Class clazz = findClass(name);
+ return resolveClass(clazz, resolve);
+ } catch (ClassNotFoundException ignored) {
+ // Ignore it
+ }
+ }
+
+ throw new ClassNotFoundException(name);
+ }
+
+ private Class resolveClass(Class clazz, boolean resolve) {
+ if (resolve) {
+ resolveClass(clazz);
+ }
+ return clazz;
+ }
+
+ private String[] toResources(String[] classes) {
+ String[] resources = new String[classes.length];
+ for (int i = 0; i < classes.length; i++) {
+ String className = classes[i];
+ resources[i] = className.replace('.', '/');
+ }
+ return resources;
+ }
+
+ public String toString() {
+ return "[" + getClass().getName() + "]";
+ }
+
+}
Propchange: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-commits-help@ws.apache.org
Re: svn commit: r504392 - /incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java
Posted by Raymond Feng <en...@gmail.com>.
Hi,
We can subclass MultiParentClassLoader to implement the
CompositeClassLoader. The parents can be derived from the dependencies as
described by import/export in the contributions.
Thanks,
Raymond
----- Original Message -----
From: "Jeremy Boynes" <jb...@apache.org>
To: <tu...@ws.apache.org>
Sent: Tuesday, February 06, 2007 7:14 PM
Subject: Re: svn commit: r504392 -
/incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java
> How does this relate to the existing CompositeClassLoader?
> --
> Jeremy
>
> On Feb 6, 2007, at 4:48 PM, rfeng@apache.org wrote:
>
>> Author: rfeng
>> Date: Tue Feb 6 16:48:21 2007
>> New Revision: 504392
>>
>> URL: http://svn.apache.org/viewvc?view=rev&rev=504392
>> Log:
>> Copy the MultiParentClassLoader from Axis2
>>
>> Added:
>> incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/
>> tuscany/spi/util/MultiParentClassLoader.java (with props)
>>
>> Added: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/
>> apache/tuscany/spi/util/MultiParentClassLoader.java
>> URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/kernel/
>> spi/src/main/java/org/apache/tuscany/spi/util/
>> MultiParentClassLoader.java?view=auto&rev=504392
>> ======================================================================
>> ========
>> --- incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/
>> tuscany/spi/util/MultiParentClassLoader.java (added)
>> +++ incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/
>> tuscany/spi/util/MultiParentClassLoader.java Tue Feb 6 16:48:21 2007
>> @@ -0,0 +1,402 @@
>> +/*
>> + * 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.spi.util;
>> +
>> +import java.beans.Introspector;
>> +import java.io.IOException;
>> +import java.net.URL;
>> +import java.net.URLClassLoader;
>> +import java.net.URLStreamHandlerFactory;
>> +import java.util.ArrayList;
>> +import java.util.Collection;
>> +import java.util.Collections;
>> +import java.util.Enumeration;
>> +import java.util.List;
>> +import java.util.Set;
>> +
>> +/**
>> + * A MultiParentClassLoader is a simple extension of the URLClassLoader
>> that
>> + * simply changes the single parent class loader model to support a
>> list of
>> + * parent class loaders. Each operation that accesses a parent, has
>> been
>> + * replaced with a operation that checks each parent in order. This
>> getParent
>> + * method of this class will always return null, which may be
>> interpreted by the
>> + * calling code to mean that this class loader is a direct child of the
>> system
>> + * class loader.
>> + *
>> + * @version $Rev$ $Date$
>> + */
>> +public class MultiParentClassLoader extends URLClassLoader {
>> + private boolean destroyed;
>> + private final String[] hiddenClasses;
>> + private final String[] hiddenResources;
>> + private final boolean inverseClassLoading;
>> + private final String[] nonOverridableClasses;
>> + private final String[] nonOverridableResources;
>> +
>> + private final ClassLoader[] parents;
>> +
>> + /**
>> + * Creates a named class loader with no parents.
>> + *
>> + * @param urls the urls from which this class loader will classes
>> and
>> + * resources
>> + */
>> + public MultiParentClassLoader(URL[] urls) {
>> + super(urls);
>> + parents = new ClassLoader[]
>> {ClassLoader.getSystemClassLoader()};
>> + inverseClassLoading = false;
>> + hiddenClasses = new String[0];
>> + nonOverridableClasses = new String[0];
>> + hiddenResources = new String[0];
>> + nonOverridableResources = new String[0];
>> + }
>> +
>> + /**
>> + * Creates a named class loader as a child of the specified parent.
>> + *
>> + * @param urls the urls from which this class loader will classes
>> and
>> + * resources
>> + * @param parent the parent of this class loader
>> + */
>> + public MultiParentClassLoader(URL[] urls, ClassLoader parent) {
>> + this(urls, new ClassLoader[] {parent});
>> + }
>> +
>> + public MultiParentClassLoader(URL[] urls,
>> + ClassLoader parent,
>> + boolean inverseClassLoading,
>> + String[] hiddenClasses,
>> + String[] nonOverridableClasses) {
>> + this(urls, new ClassLoader[] {parent}, inverseClassLoading,
>> hiddenClasses, nonOverridableClasses);
>> + }
>> +
>> + /**
>> + * Creates a named class loader as a child of the specified parent
>> and using
>> + * the specified URLStreamHandlerFactory for accessing the urls..
>> + *
>> + * @param urls the urls from which this class loader will classes
>> and
>> + * resources
>> + * @param parent the parent of this class loader
>> + * @param factory the URLStreamHandlerFactory used to access the
>> urls
>> + */
>> + public MultiParentClassLoader(URL[] urls, ClassLoader parent,
>> URLStreamHandlerFactory factory) {
>> + this(urls, new ClassLoader[] {parent}, factory);
>> + }
>> +
>> + /**
>> + * Creates a named class loader as a child of the specified
>> parents.
>> + *
>> + * @param urls the urls from which this class loader will classes
>> and
>> + * resources
>> + * @param parents the parents of this class loader
>> + */
>> + public MultiParentClassLoader(URL[] urls, ClassLoader[] parents) {
>> + super(urls);
>> + this.parents = copyParents(parents);
>> + inverseClassLoading = false;
>> + hiddenClasses = new String[0];
>> + nonOverridableClasses = new String[0];
>> + hiddenResources = new String[0];
>> + nonOverridableResources = new String[0];
>> + }
>> +
>> + public MultiParentClassLoader(URL[] urls,
>> + ClassLoader[] parents,
>> + boolean inverseClassLoading,
>> + Collection<String> hiddenClasses,
>> + Collection<String>
>> nonOverridableClasses) {
>> + this(urls, parents, inverseClassLoading, (String[])
>> hiddenClasses.toArray(new String[hiddenClasses.size()]),
>> + (String[])nonOverridableClasses.toArray(new String
>> [nonOverridableClasses.size()]));
>> + }
>> +
>> + public MultiParentClassLoader(URL[] urls,
>> + ClassLoader[] parents,
>> + boolean inverseClassLoading,
>> + String[] hiddenClasses,
>> + String[] nonOverridableClasses) {
>> + super(urls);
>> + this.parents = copyParents(parents);
>> + this.inverseClassLoading = inverseClassLoading;
>> + this.hiddenClasses = hiddenClasses;
>> + this.nonOverridableClasses = nonOverridableClasses;
>> + hiddenResources = toResources(hiddenClasses);
>> + nonOverridableResources = toResources(nonOverridableClasses);
>> + }
>> +
>> + /**
>> + * Creates a named class loader as a child of the specified parents
>> and
>> + * using the specified URLStreamHandlerFactory for accessing the
>> urls..
>> + *
>> + * @param urls the urls from which this class loader will classes
>> and
>> + * resources
>> + * @param parents the parents of this class loader
>> + * @param factory the URLStreamHandlerFactory used to access the
>> urls
>> + */
>> + public MultiParentClassLoader(URL[] urls, ClassLoader[] parents,
>> URLStreamHandlerFactory factory) {
>> + super(urls, null, factory);
>> + this.parents = copyParents(parents);
>> + inverseClassLoading = false;
>> + hiddenClasses = new String[0];
>> + nonOverridableClasses = new String[0];
>> + hiddenResources = new String[0];
>> + nonOverridableResources = new String[0];
>> + }
>> +
>> + private static ClassLoader[] copyParents(ClassLoader[] parents) {
>> + ClassLoader[] newParentsArray = new ClassLoader
>> [parents.length];
>> + for (int i = 0; i < parents.length; i++) {
>> + ClassLoader parent = parents[i];
>> + if (parent == null) {
>> + throw new RuntimeException("parent[" + i + "] is
>> null");
>> + }
>> + newParentsArray[i] = parent;
>> + }
>> + return newParentsArray;
>> + }
>> +
>> + public void addURL(URL url) {
>> + // todo this needs a security check
>> + super.addURL(url);
>> + }
>> +
>> + public void destroy() {
>> + synchronized (this) {
>> + if (destroyed) {
>> + return;
>> + }
>> + destroyed = true;
>> + }
>> +
>> + // clearSoftCache(ObjectInputStream.class, "subclassAudits");
>> + // clearSoftCache(ObjectOutputStream.class, "subclassAudits");
>> + // clearSoftCache(ObjectStreamClass.class, "localDescs");
>> + // clearSoftCache(ObjectStreamClass.class, "reflectors");
>> +
>> + // The beanInfoCache in java.beans.Introspector will hold on to
>> Classes
>> + // which
>> + // it has introspected. If we don't flush the cache, we may run
>> out of
>> + // Permanent Generation space.
>> + Introspector.flushCaches();
>> + }
>> +
>> + public Enumeration<URL> findResources(String name) throws
>> IOException {
>> + if (isDestroyed()) {
>> + Set<URL> emptySet = Collections.emptySet();
>> + return Collections.enumeration(emptySet);
>> + }
>> +
>> + List<URL> resources = new ArrayList<URL>();
>> +
>> + //
>> + // if we are using inverse class loading, add the resources
>> from local
>> + // urls first
>> + //
>> + if (inverseClassLoading && !isDestroyed()) {
>> + List<URL> myResources = Collections.list
>> (super.findResources(name));
>> + resources.addAll(myResources);
>> + }
>> +
>> + //
>> + // Add parent resources
>> + //
>> + for (int i = 0; i < parents.length; i++) {
>> + ClassLoader parent = parents[i];
>> + List<URL> parentResources = Collections.list
>> (parent.getResources(name));
>> + resources.addAll(parentResources);
>> + }
>> +
>> + //
>> + // if we are not using inverse class loading, add the resources
>> from
>> + // local urls now
>> + //
>> + if (!inverseClassLoading && !isDestroyed()) {
>> + List<URL> myResources = Collections.list
>> (super.findResources(name));
>> + resources.addAll(myResources);
>> + }
>> +
>> + return Collections.enumeration(resources);
>> + }
>> +
>> + /**
>> + * Gets the parents of this class loader.
>> + *
>> + * @return the parents of this class loader
>> + */
>> + public ClassLoader[] getParents() {
>> + return parents;
>> + }
>> +
>> + public URL getResource(String name) {
>> + if (isDestroyed()) {
>> + return null;
>> + }
>> +
>> + //
>> + // if we are using inverse class loading, check local urls
>> first
>> + //
>> + if (inverseClassLoading && !isDestroyed() && !
>> isNonOverridableResource(name)) {
>> + URL url = findResource(name);
>> + if (url != null) {
>> + return url;
>> + }
>> + }
>> +
>> + //
>> + // Check parent class loaders
>> + //
>> + if (!isHiddenResource(name)) {
>> + for (int i = 0; i < parents.length; i++) {
>> + ClassLoader parent = parents[i];
>> + URL url = parent.getResource(name);
>> + if (url != null) {
>> + return url;
>> + }
>> + }
>> + }
>> +
>> + //
>> + // if we are not using inverse class loading, check local urls
>> now
>> + //
>> + // don't worry about excluding non-overridable resources
>> here... we
>> + // have alredy checked he parent and the parent didn't have the
>> + // resource, so we can override now
>> + if (!isDestroyed()) {
>> + // parents didn't have the resource; attempt to load it
>> from my urls
>> + return findResource(name);
>> + }
>> +
>> + return null;
>> + }
>> +
>> + public synchronized boolean isDestroyed() {
>> + return destroyed;
>> + }
>> +
>> + private boolean isHiddenClass(String name) {
>> + for (int i = 0; i < hiddenClasses.length; i++) {
>> + if (name.startsWith(hiddenClasses[i])) {
>> + return true;
>> + }
>> + }
>> + return false;
>> + }
>> +
>> + private boolean isHiddenResource(String name) {
>> + for (int i = 0; i < hiddenResources.length; i++) {
>> + if (name.startsWith(hiddenResources[i])) {
>> + return true;
>> + }
>> + }
>> + return false;
>> + }
>> +
>> + private boolean isNonOverridableClass(String name) {
>> + for (int i = 0; i < nonOverridableClasses.length; i++) {
>> + if (name.startsWith(nonOverridableClasses[i])) {
>> + return true;
>> + }
>> + }
>> + return false;
>> + }
>> +
>> + private boolean isNonOverridableResource(String name) {
>> + for (int i = 0; i < nonOverridableResources.length; i++) {
>> + if (name.startsWith(nonOverridableResources[i])) {
>> + return true;
>> + }
>> + }
>> + return false;
>> + }
>> +
>> + @SuppressWarnings("unchecked")
>> + protected synchronized Class loadClass(String name, boolean
>> resolve) throws ClassNotFoundException {
>> + //
>> + // Check if class is in the loaded classes cache
>> + //
>> + Class cachedClass = findLoadedClass(name);
>> + if (cachedClass != null) {
>> + return resolveClass(cachedClass, resolve);
>> + }
>> +
>> + //
>> + // if we are using inverse class loading, check local urls
>> first
>> + //
>> + if (inverseClassLoading && !isDestroyed() && !
>> isNonOverridableClass(name)) {
>> + try {
>> + Class clazz = findClass(name);
>> + return resolveClass(clazz, resolve);
>> + } catch (ClassNotFoundException ignored) {
>> + // Ignore it
>> + }
>> + }
>> +
>> + //
>> + // Check parent class loaders
>> + //
>> + if (!isHiddenClass(name)) {
>> + for (int i = 0; i < parents.length; i++) {
>> + ClassLoader parent = parents[i];
>> + try {
>> + Class clazz = parent.loadClass(name);
>> + return resolveClass(clazz, resolve);
>> + } catch (ClassNotFoundException ignored) {
>> + // this parent didn't have the class; try the next
>> one
>> + }
>> + }
>> + }
>> +
>> + //
>> + // if we are not using inverse class loading, check local urls
>> now
>> + //
>> + // don't worry about excluding non-overridable classes here...
>> we
>> + // have alredy checked he parent and the parent didn't have the
>> + // class, so we can override now
>> + if (!isDestroyed()) {
>> + try {
>> + Class clazz = findClass(name);
>> + return resolveClass(clazz, resolve);
>> + } catch (ClassNotFoundException ignored) {
>> + // Ignore it
>> + }
>> + }
>> +
>> + throw new ClassNotFoundException(name);
>> + }
>> +
>> + private Class resolveClass(Class clazz, boolean resolve) {
>> + if (resolve) {
>> + resolveClass(clazz);
>> + }
>> + return clazz;
>> + }
>> +
>> + private String[] toResources(String[] classes) {
>> + String[] resources = new String[classes.length];
>> + for (int i = 0; i < classes.length; i++) {
>> + String className = classes[i];
>> + resources[i] = className.replace('.', '/');
>> + }
>> + return resources;
>> + }
>> +
>> + public String toString() {
>> + return "[" + getClass().getName() + "]";
>> + }
>> +
>> +}
>>
>> Propchange: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/
>> apache/tuscany/spi/util/MultiParentClassLoader.java
>> ----------------------------------------------------------------------
>> --------
>> svn:eol-style = native
>>
>> Propchange: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/
>> apache/tuscany/spi/util/MultiParentClassLoader.java
>> ----------------------------------------------------------------------
>> --------
>> svn:keywords = Rev Date
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tuscany-commits-unsubscribe@ws.apache.org
>> For additional commands, e-mail: tuscany-commits-help@ws.apache.org
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org
Re: svn commit: r504392 - /incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/tuscany/spi/util/MultiParentClassLoader.java
Posted by Jeremy Boynes <jb...@apache.org>.
How does this relate to the existing CompositeClassLoader?
--
Jeremy
On Feb 6, 2007, at 4:48 PM, rfeng@apache.org wrote:
> Author: rfeng
> Date: Tue Feb 6 16:48:21 2007
> New Revision: 504392
>
> URL: http://svn.apache.org/viewvc?view=rev&rev=504392
> Log:
> Copy the MultiParentClassLoader from Axis2
>
> Added:
> incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/
> tuscany/spi/util/MultiParentClassLoader.java (with props)
>
> Added: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/
> apache/tuscany/spi/util/MultiParentClassLoader.java
> URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/kernel/
> spi/src/main/java/org/apache/tuscany/spi/util/
> MultiParentClassLoader.java?view=auto&rev=504392
> ======================================================================
> ========
> --- incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/
> tuscany/spi/util/MultiParentClassLoader.java (added)
> +++ incubator/tuscany/java/sca/kernel/spi/src/main/java/org/apache/
> tuscany/spi/util/MultiParentClassLoader.java Tue Feb 6 16:48:21 2007
> @@ -0,0 +1,402 @@
> +/*
> + * 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.spi.util;
> +
> +import java.beans.Introspector;
> +import java.io.IOException;
> +import java.net.URL;
> +import java.net.URLClassLoader;
> +import java.net.URLStreamHandlerFactory;
> +import java.util.ArrayList;
> +import java.util.Collection;
> +import java.util.Collections;
> +import java.util.Enumeration;
> +import java.util.List;
> +import java.util.Set;
> +
> +/**
> + * A MultiParentClassLoader is a simple extension of the
> URLClassLoader that
> + * simply changes the single parent class loader model to support
> a list of
> + * parent class loaders. Each operation that accesses a parent,
> has been
> + * replaced with a operation that checks each parent in order.
> This getParent
> + * method of this class will always return null, which may be
> interpreted by the
> + * calling code to mean that this class loader is a direct child
> of the system
> + * class loader.
> + *
> + * @version $Rev$ $Date$
> + */
> +public class MultiParentClassLoader extends URLClassLoader {
> + private boolean destroyed;
> + private final String[] hiddenClasses;
> + private final String[] hiddenResources;
> + private final boolean inverseClassLoading;
> + private final String[] nonOverridableClasses;
> + private final String[] nonOverridableResources;
> +
> + private final ClassLoader[] parents;
> +
> + /**
> + * Creates a named class loader with no parents.
> + *
> + * @param urls the urls from which this class loader will
> classes and
> + * resources
> + */
> + public MultiParentClassLoader(URL[] urls) {
> + super(urls);
> + parents = new ClassLoader[]
> {ClassLoader.getSystemClassLoader()};
> + inverseClassLoading = false;
> + hiddenClasses = new String[0];
> + nonOverridableClasses = new String[0];
> + hiddenResources = new String[0];
> + nonOverridableResources = new String[0];
> + }
> +
> + /**
> + * Creates a named class loader as a child of the specified
> parent.
> + *
> + * @param urls the urls from which this class loader will
> classes and
> + * resources
> + * @param parent the parent of this class loader
> + */
> + public MultiParentClassLoader(URL[] urls, ClassLoader parent) {
> + this(urls, new ClassLoader[] {parent});
> + }
> +
> + public MultiParentClassLoader(URL[] urls,
> + ClassLoader parent,
> + boolean inverseClassLoading,
> + String[] hiddenClasses,
> + String[] nonOverridableClasses) {
> + this(urls, new ClassLoader[] {parent},
> inverseClassLoading, hiddenClasses, nonOverridableClasses);
> + }
> +
> + /**
> + * Creates a named class loader as a child of the specified
> parent and using
> + * the specified URLStreamHandlerFactory for accessing the urls..
> + *
> + * @param urls the urls from which this class loader will
> classes and
> + * resources
> + * @param parent the parent of this class loader
> + * @param factory the URLStreamHandlerFactory used to access
> the urls
> + */
> + public MultiParentClassLoader(URL[] urls, ClassLoader parent,
> URLStreamHandlerFactory factory) {
> + this(urls, new ClassLoader[] {parent}, factory);
> + }
> +
> + /**
> + * Creates a named class loader as a child of the specified
> parents.
> + *
> + * @param urls the urls from which this class loader will
> classes and
> + * resources
> + * @param parents the parents of this class loader
> + */
> + public MultiParentClassLoader(URL[] urls, ClassLoader[]
> parents) {
> + super(urls);
> + this.parents = copyParents(parents);
> + inverseClassLoading = false;
> + hiddenClasses = new String[0];
> + nonOverridableClasses = new String[0];
> + hiddenResources = new String[0];
> + nonOverridableResources = new String[0];
> + }
> +
> + public MultiParentClassLoader(URL[] urls,
> + ClassLoader[] parents,
> + boolean inverseClassLoading,
> + Collection<String> hiddenClasses,
> + Collection<String>
> nonOverridableClasses) {
> + this(urls, parents, inverseClassLoading, (String[])
> hiddenClasses.toArray(new String[hiddenClasses.size()]),
> + (String[])nonOverridableClasses.toArray(new String
> [nonOverridableClasses.size()]));
> + }
> +
> + public MultiParentClassLoader(URL[] urls,
> + ClassLoader[] parents,
> + boolean inverseClassLoading,
> + String[] hiddenClasses,
> + String[] nonOverridableClasses) {
> + super(urls);
> + this.parents = copyParents(parents);
> + this.inverseClassLoading = inverseClassLoading;
> + this.hiddenClasses = hiddenClasses;
> + this.nonOverridableClasses = nonOverridableClasses;
> + hiddenResources = toResources(hiddenClasses);
> + nonOverridableResources = toResources(nonOverridableClasses);
> + }
> +
> + /**
> + * Creates a named class loader as a child of the specified
> parents and
> + * using the specified URLStreamHandlerFactory for accessing
> the urls..
> + *
> + * @param urls the urls from which this class loader will
> classes and
> + * resources
> + * @param parents the parents of this class loader
> + * @param factory the URLStreamHandlerFactory used to access
> the urls
> + */
> + public MultiParentClassLoader(URL[] urls, ClassLoader[]
> parents, URLStreamHandlerFactory factory) {
> + super(urls, null, factory);
> + this.parents = copyParents(parents);
> + inverseClassLoading = false;
> + hiddenClasses = new String[0];
> + nonOverridableClasses = new String[0];
> + hiddenResources = new String[0];
> + nonOverridableResources = new String[0];
> + }
> +
> + private static ClassLoader[] copyParents(ClassLoader[] parents) {
> + ClassLoader[] newParentsArray = new ClassLoader
> [parents.length];
> + for (int i = 0; i < parents.length; i++) {
> + ClassLoader parent = parents[i];
> + if (parent == null) {
> + throw new RuntimeException("parent[" + i + "] is
> null");
> + }
> + newParentsArray[i] = parent;
> + }
> + return newParentsArray;
> + }
> +
> + public void addURL(URL url) {
> + // todo this needs a security check
> + super.addURL(url);
> + }
> +
> + public void destroy() {
> + synchronized (this) {
> + if (destroyed) {
> + return;
> + }
> + destroyed = true;
> + }
> +
> + // clearSoftCache(ObjectInputStream.class, "subclassAudits");
> + // clearSoftCache(ObjectOutputStream.class,
> "subclassAudits");
> + // clearSoftCache(ObjectStreamClass.class, "localDescs");
> + // clearSoftCache(ObjectStreamClass.class, "reflectors");
> +
> + // The beanInfoCache in java.beans.Introspector will hold
> on to Classes
> + // which
> + // it has introspected. If we don't flush the cache, we
> may run out of
> + // Permanent Generation space.
> + Introspector.flushCaches();
> + }
> +
> + public Enumeration<URL> findResources(String name) throws
> IOException {
> + if (isDestroyed()) {
> + Set<URL> emptySet = Collections.emptySet();
> + return Collections.enumeration(emptySet);
> + }
> +
> + List<URL> resources = new ArrayList<URL>();
> +
> + //
> + // if we are using inverse class loading, add the
> resources from local
> + // urls first
> + //
> + if (inverseClassLoading && !isDestroyed()) {
> + List<URL> myResources = Collections.list
> (super.findResources(name));
> + resources.addAll(myResources);
> + }
> +
> + //
> + // Add parent resources
> + //
> + for (int i = 0; i < parents.length; i++) {
> + ClassLoader parent = parents[i];
> + List<URL> parentResources = Collections.list
> (parent.getResources(name));
> + resources.addAll(parentResources);
> + }
> +
> + //
> + // if we are not using inverse class loading, add the
> resources from
> + // local urls now
> + //
> + if (!inverseClassLoading && !isDestroyed()) {
> + List<URL> myResources = Collections.list
> (super.findResources(name));
> + resources.addAll(myResources);
> + }
> +
> + return Collections.enumeration(resources);
> + }
> +
> + /**
> + * Gets the parents of this class loader.
> + *
> + * @return the parents of this class loader
> + */
> + public ClassLoader[] getParents() {
> + return parents;
> + }
> +
> + public URL getResource(String name) {
> + if (isDestroyed()) {
> + return null;
> + }
> +
> + //
> + // if we are using inverse class loading, check local urls
> first
> + //
> + if (inverseClassLoading && !isDestroyed() && !
> isNonOverridableResource(name)) {
> + URL url = findResource(name);
> + if (url != null) {
> + return url;
> + }
> + }
> +
> + //
> + // Check parent class loaders
> + //
> + if (!isHiddenResource(name)) {
> + for (int i = 0; i < parents.length; i++) {
> + ClassLoader parent = parents[i];
> + URL url = parent.getResource(name);
> + if (url != null) {
> + return url;
> + }
> + }
> + }
> +
> + //
> + // if we are not using inverse class loading, check local
> urls now
> + //
> + // don't worry about excluding non-overridable resources
> here... we
> + // have alredy checked he parent and the parent didn't
> have the
> + // resource, so we can override now
> + if (!isDestroyed()) {
> + // parents didn't have the resource; attempt to load
> it from my urls
> + return findResource(name);
> + }
> +
> + return null;
> + }
> +
> + public synchronized boolean isDestroyed() {
> + return destroyed;
> + }
> +
> + private boolean isHiddenClass(String name) {
> + for (int i = 0; i < hiddenClasses.length; i++) {
> + if (name.startsWith(hiddenClasses[i])) {
> + return true;
> + }
> + }
> + return false;
> + }
> +
> + private boolean isHiddenResource(String name) {
> + for (int i = 0; i < hiddenResources.length; i++) {
> + if (name.startsWith(hiddenResources[i])) {
> + return true;
> + }
> + }
> + return false;
> + }
> +
> + private boolean isNonOverridableClass(String name) {
> + for (int i = 0; i < nonOverridableClasses.length; i++) {
> + if (name.startsWith(nonOverridableClasses[i])) {
> + return true;
> + }
> + }
> + return false;
> + }
> +
> + private boolean isNonOverridableResource(String name) {
> + for (int i = 0; i < nonOverridableResources.length; i++) {
> + if (name.startsWith(nonOverridableResources[i])) {
> + return true;
> + }
> + }
> + return false;
> + }
> +
> + @SuppressWarnings("unchecked")
> + protected synchronized Class loadClass(String name, boolean
> resolve) throws ClassNotFoundException {
> + //
> + // Check if class is in the loaded classes cache
> + //
> + Class cachedClass = findLoadedClass(name);
> + if (cachedClass != null) {
> + return resolveClass(cachedClass, resolve);
> + }
> +
> + //
> + // if we are using inverse class loading, check local urls
> first
> + //
> + if (inverseClassLoading && !isDestroyed() && !
> isNonOverridableClass(name)) {
> + try {
> + Class clazz = findClass(name);
> + return resolveClass(clazz, resolve);
> + } catch (ClassNotFoundException ignored) {
> + // Ignore it
> + }
> + }
> +
> + //
> + // Check parent class loaders
> + //
> + if (!isHiddenClass(name)) {
> + for (int i = 0; i < parents.length; i++) {
> + ClassLoader parent = parents[i];
> + try {
> + Class clazz = parent.loadClass(name);
> + return resolveClass(clazz, resolve);
> + } catch (ClassNotFoundException ignored) {
> + // this parent didn't have the class; try the
> next one
> + }
> + }
> + }
> +
> + //
> + // if we are not using inverse class loading, check local
> urls now
> + //
> + // don't worry about excluding non-overridable classes
> here... we
> + // have alredy checked he parent and the parent didn't
> have the
> + // class, so we can override now
> + if (!isDestroyed()) {
> + try {
> + Class clazz = findClass(name);
> + return resolveClass(clazz, resolve);
> + } catch (ClassNotFoundException ignored) {
> + // Ignore it
> + }
> + }
> +
> + throw new ClassNotFoundException(name);
> + }
> +
> + private Class resolveClass(Class clazz, boolean resolve) {
> + if (resolve) {
> + resolveClass(clazz);
> + }
> + return clazz;
> + }
> +
> + private String[] toResources(String[] classes) {
> + String[] resources = new String[classes.length];
> + for (int i = 0; i < classes.length; i++) {
> + String className = classes[i];
> + resources[i] = className.replace('.', '/');
> + }
> + return resources;
> + }
> +
> + public String toString() {
> + return "[" + getClass().getName() + "]";
> + }
> +
> +}
>
> Propchange: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/
> apache/tuscany/spi/util/MultiParentClassLoader.java
> ----------------------------------------------------------------------
> --------
> svn:eol-style = native
>
> Propchange: incubator/tuscany/java/sca/kernel/spi/src/main/java/org/
> apache/tuscany/spi/util/MultiParentClassLoader.java
> ----------------------------------------------------------------------
> --------
> svn:keywords = Rev Date
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-commits-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-commits-help@ws.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org