You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by Jeremy Boynes <jb...@apache.org> on 2007/02/07 04:14:49 UTC

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


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