geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joe Bohn <joe.b...@earthlink.net>
Subject Re: svn commit: r712326 - in /geronimo/server/trunk: framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/classloader/ framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ framework/modules/geronimo-kerne...
Date Tue, 18 Nov 2008 17:02:34 GMT
Just a heads up that I *think* there are still some issues with this 
change.

It appears that the hiddenResource processing from the 
MultiParentClassloader was removed.  I think this has resulted in some 
testsuite failures involving tld processing.  There are failures in the 
web-testsuite/test-2.1-jsps and web-testsuite/test-myfaces tests.  I'm 
looking at what would be necessary to add in the hiddenResource logic 
again hoping that will resolve the issue.

This is a really nice feature and it is great to have the capability. 
However could you please run the testsuite in the future to avoid 
problems like this (especially when introducing fundamental changes like 
this)?

BTW, I'd personally like to see the plan changes re-introduced for 
private-classes if it turns out that we need an OpenEJB release anyway 
(and at this point in time I think that is the case).  I think users are 
  more accustomed to using declarative plans for this type of thing at 
the moment and would find this helpful.

Thanks,
Joe


gdamour@apache.org wrote:
> Author: gdamour
> Date: Fri Nov  7 16:40:08 2008
> New Revision: 712326
> 
> URL: http://svn.apache.org/viewvc?rev=712326&view=rev
> Log:
> Add private-classes element which allows specific classes to be hidden from all child configurations. In effect, they are private to the configuration.
> 
> (GERONIMO-4403) Provide a mechanism to hide specific classes  of a configuration to all its children
> 
> Added:
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ChildrenConfigurationClassLoader.java
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/ClassLoadingRule.java
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/ClassLoadingRules.java
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/config/ChildrenConfigurationClassLoaderTest.java
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/repository/ClassLoadingRuleTest.java
>     geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/java/org/apache/geronimo/deployment/service/ClassLoadingRulesUtil.java
>     geronimo/server/trunk/framework/modules/geronimo-service-builder/src/test/java/org/apache/geronimo/deployment/service/ClassLoadingRulesUtilTest.java
> Modified:
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/classloader/JarFileClassLoader.java
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/Configuration.java
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/MultiParentClassLoader.java
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/DefaultArtifactResolver.java
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/Environment.java
>     geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/config/MultiParentClassLoaderTest.java
>     geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/java/org/apache/geronimo/deployment/service/EnvironmentBuilder.java
>     geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/xsd/geronimo-module-1.2.xsd
>     geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/appclient_dep_1_result.xml
>     geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/appclient_ejb_1_result.xml
>     geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/assembly_1_result.xml
>     geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/gbean_1_result.xml
>     geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/servlet_1_result.xml
>     geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/transport_1_result.xml
>     geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/transport_2_result.xml
>     geronimo/server/trunk/plugins/jetty/geronimo-jetty6/src/test/java/org/apache/geronimo/jetty6/ClassLoaderTest.java
>     geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/XmlUtil.java
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/classloader/JarFileClassLoader.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/classloader/JarFileClassLoader.java?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/classloader/JarFileClassLoader.java (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/classloader/JarFileClassLoader.java Fri Nov  7 16:40:08 2008
> @@ -16,25 +16,25 @@
>   */
>  package org.apache.geronimo.kernel.classloader;
>  
> -import java.io.IOException;
>  import java.io.File;
> -import java.net.URL;
> +import java.io.IOException;
>  import java.net.URI;
> +import java.net.URL;
>  import java.net.URLClassLoader;
>  import java.security.AccessControlContext;
>  import java.security.AccessController;
>  import java.security.CodeSource;
>  import java.security.PrivilegedAction;
> -import java.security.PrivilegedExceptionAction;
>  import java.security.PrivilegedActionException;
> +import java.security.PrivilegedExceptionAction;
>  import java.security.cert.Certificate;
> -import java.util.Collection;
>  import java.util.Enumeration;
>  import java.util.jar.Attributes;
>  import java.util.jar.Manifest;
>  
>  import org.apache.geronimo.kernel.config.MultiParentClassLoader;
>  import org.apache.geronimo.kernel.repository.Artifact;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
>  
>  /**
>   * The JarFileClassLoader that loads classes and resources from a list of JarFiles.  This method is simmilar to URLClassLoader
> @@ -78,8 +78,8 @@
>          addURLs(urls);
>      }
>  
> -    public JarFileClassLoader(Artifact id, URL[] urls, ClassLoader parent, boolean inverseClassLoading, String[] hiddenClasses, String[] nonOverridableClasses) {
> -        super(id, EMPTY_URLS, parent, inverseClassLoading, hiddenClasses, nonOverridableClasses);
> +    public JarFileClassLoader(Artifact id, URL[] urls, ClassLoader parent, ClassLoadingRules classLoadingRules) {
> +        super(id, EMPTY_URLS, parent, classLoadingRules);
>          this.acc = AccessController.getContext();
>          addURLs(urls);
>      }
> @@ -96,14 +96,8 @@
>          addURLs(urls);
>      }
>  
> -    public JarFileClassLoader(Artifact id, URL[] urls, ClassLoader[] parents, boolean inverseClassLoading, Collection hiddenClasses, Collection nonOverridableClasses) {
> -        super(id, EMPTY_URLS, parents, inverseClassLoading, hiddenClasses, nonOverridableClasses);
> -        this.acc = AccessController.getContext();
> -        addURLs(urls);
> -    }
> -
> -    public JarFileClassLoader(Artifact id, URL[] urls, ClassLoader[] parents, boolean inverseClassLoading, String[] hiddenClasses, String[] nonOverridableClasses) {
> -        super(id, EMPTY_URLS, parents, inverseClassLoading, hiddenClasses, nonOverridableClasses);
> +    public JarFileClassLoader(Artifact id, URL[] urls, ClassLoader[] parents, ClassLoadingRules classLoadingRules) {
> +        super(id, EMPTY_URLS, parents, classLoadingRules);
>          this.acc = AccessController.getContext();
>          addURLs(urls);
>      }
> 
> Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ChildrenConfigurationClassLoader.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ChildrenConfigurationClassLoader.java?rev=712326&view=auto
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ChildrenConfigurationClassLoader.java (added)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ChildrenConfigurationClassLoader.java Fri Nov  7 16:40:08 2008
> @@ -0,0 +1,92 @@
> +/*
> + * 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.geronimo.kernel.config;
> +
> +import java.io.IOException;
> +import java.net.MalformedURLException;
> +import java.net.URL;
> +import java.security.SecureClassLoader;
> +import java.util.Collections;
> +import java.util.Enumeration;
> +import java.util.List;
> +
> +import org.apache.geronimo.kernel.repository.ClassLoadingRule;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
> +
> +import sun.misc.CompoundEnumeration;
> +
> +/**
> + *
> + * @version $Rev:$ $Date:$
> + */
> +public class ChildrenConfigurationClassLoader extends SecureClassLoader {
> +
> +    private final ClassLoadingRules rules;
> +
> +    public ChildrenConfigurationClassLoader(ClassLoader parent, ClassLoadingRules rules) {
> +        super(parent);
> +        if (null == rules) {
> +            throw new IllegalArgumentException("rules is required");
> +        }
> +        this.rules = rules;
> +    }
> +
> +    public Class<?> loadClass(String name, List<ClassLoader> visitedClassLoaders) throws ClassNotFoundException {
> +        return loadClass(name, false, visitedClassLoaders);
> +    }
> +    
> +    protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
> +        return loadClass(name, resolve, Collections.EMPTY_LIST);
> +    }
> +
> +    protected synchronized Class<?> loadClass(String name, boolean resolve, List<ClassLoader> visitedClassLoaders)
> +            throws ClassNotFoundException {
> +        ClassLoadingRule privateRule = rules.getPrivateRule();
> +        ClassLoader parent = getParent();
> +        if (privateRule.isFilteredClass(name)) {
> +            throw new ClassNotFoundException(name + " is hidden by classloader " + parent);
> +        }
> +        
> +        if (parent instanceof MultiParentClassLoader) {
> +            try {
> +                return ((MultiParentClassLoader) parent).loadClassInternal(name, resolve, visitedClassLoaders);
> +            } catch (MalformedURLException e) {
> +            }
> +        }
> +        return super.loadClass(name, resolve);
> +    }
> +    
> +    public URL getResource(String name) {
> +        ClassLoadingRule privateRule = rules.getPrivateRule();
> +        if (privateRule.isFilteredResource(name)) {
> +            return null;
> +        }
> +        return super.getResource(name);
> +    }
> +
> +    public Enumeration<URL> getResources(String name) throws IOException {
> +        ClassLoadingRule privateRule = rules.getPrivateRule();
> +        if (privateRule.isFilteredResource(name)) {
> +            return new CompoundEnumeration(new Enumeration[0]);
> +        }
> +        return super.getResources(name);
> +    }
> +
> +}
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/Configuration.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/Configuration.java?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/Configuration.java (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/Configuration.java Fri Nov  7 16:40:08 2008
> @@ -25,6 +25,7 @@
>  import java.util.Collection;
>  import java.util.Collections;
>  import java.util.HashMap;
> +import java.util.HashSet;
>  import java.util.Iterator;
>  import java.util.LinkedHashMap;
>  import java.util.LinkedHashSet;
> @@ -32,13 +33,10 @@
>  import java.util.ListIterator;
>  import java.util.Map;
>  import java.util.Set;
> -import java.util.HashSet;
>  
>  import javax.management.MalformedObjectNameException;
>  import javax.management.ObjectName;
>  
> -import org.slf4j.Logger;
> -import org.slf4j.LoggerFactory;
>  import org.apache.geronimo.gbean.AbstractName;
>  import org.apache.geronimo.gbean.AbstractNameQuery;
>  import org.apache.geronimo.gbean.GBeanData;
> @@ -51,10 +49,14 @@
>  import org.apache.geronimo.kernel.Naming;
>  import org.apache.geronimo.kernel.classloader.JarFileClassLoader;
>  import org.apache.geronimo.kernel.repository.Artifact;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRule;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
>  import org.apache.geronimo.kernel.repository.Dependency;
>  import org.apache.geronimo.kernel.repository.Environment;
>  import org.apache.geronimo.kernel.repository.ImportType;
>  import org.apache.geronimo.kernel.repository.MissingDependencyException;
> +import org.slf4j.Logger;
> +import org.slf4j.LoggerFactory;
>  
>  /**
>   * A Configuration represents a collection of runnable services that can be
> @@ -170,6 +172,11 @@
>      private final MultiParentClassLoader configurationClassLoader;
>  
>      /**
> +     * The ClassLoader used by children configurations.
> +     */
> +    private final ClassLoader childrenConfigurationClassLoader;
> +
> +    /**
>       * The relative class path (URI) of this configuation.
>       */
>      private final LinkedHashSet<String> classPath;
> @@ -204,6 +211,7 @@
>          classPath = null;
>          configurationResolver = null;
>          configurationClassLoader = null;
> +        childrenConfigurationClassLoader = null;
>          naming = null;
>      }
>  
> @@ -266,6 +274,9 @@
>              // Build the configuration class loader
>              //
>              configurationClassLoader = createConfigurationClasssLoader(parents, environment, classPath);
> +            
> +            ClassLoadingRules rules = environment.getClassLoadingRules();
> +            childrenConfigurationClassLoader = new ChildrenConfigurationClassLoader(configurationClassLoader, rules);
>  
>              //
>              // Get all service parents in depth first order
> @@ -333,22 +344,19 @@
>              parentClassLoaders = new ClassLoader[classParents.size()];
>              for (ListIterator iterator = classParents.listIterator(); iterator.hasNext();) {
>                  Configuration configuration = (Configuration) iterator.next();
> -                parentClassLoaders[iterator.previousIndex()] = configuration.getConfigurationClassLoader();
> +                parentClassLoaders[iterator.previousIndex()] = configuration.childrenConfigurationClassLoader;
>              }
>          }
>  
> -        // hidden classes
> -        Set<String> hiddenClassesSet = environment.getHiddenClasses();
> -        String[] hiddenClasses = hiddenClassesSet.toArray(new String[hiddenClassesSet.size()]);
> -
>          // we need to propagate the non-overrideable classes from parents
> -        LinkedHashSet<String> nonOverridableSet = new LinkedHashSet<String>(environment.getNonOverrideableClasses());
> +        ClassLoadingRules classLoadingRules = environment.getClassLoadingRules();
> +        ClassLoadingRule nonOverrideableRule = classLoadingRules.getNonOverrideableRule();
>          for (Configuration parent : classParents) {
> -
>              Environment parentEnvironment = parent.getEnvironment();
> -            nonOverridableSet.addAll(parentEnvironment.getNonOverrideableClasses());
> +            ClassLoadingRules parentClassLoadingRules = parentEnvironment.getClassLoadingRules();
> +            ClassLoadingRule parentNonOverrideableRule = parentClassLoadingRules.getNonOverrideableRule();
> +            nonOverrideableRule.merge(parentNonOverrideableRule);
>          }
> -        String[] nonOverridableClasses = nonOverridableSet.toArray(new String[nonOverridableSet.size()]);
>  
>          if (log.isDebugEnabled()) {
>              StringBuffer buf = new StringBuffer("ClassLoader structure for configuration ").append(id).append("\n");
> @@ -377,16 +385,12 @@
>              return new JarFileClassLoader(environment.getConfigId(),
>                      urls,
>                      parentClassLoaders,
> -                    environment.isInverseClassLoading(),
> -                    hiddenClasses,
> -                    nonOverridableClasses);
> +                    classLoadingRules);
>          } else {
>              return new MultiParentClassLoader(environment.getConfigId(),
>                      urls,
>                      parentClassLoaders,
> -                    environment.isInverseClassLoading(),
> -                    hiddenClasses,
> -                    nonOverridableClasses);
> +                    classLoadingRules);
>          }
>      }
>  
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/MultiParentClassLoader.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/MultiParentClassLoader.java?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/MultiParentClassLoader.java (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/MultiParentClassLoader.java Fri Nov  7 16:40:08 2008
> @@ -27,7 +27,6 @@
>  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.HashSet;
> @@ -36,11 +35,13 @@
>  import java.util.Map;
>  import java.util.Set;
>  
> -import org.slf4j.Logger;
> -import org.slf4j.LoggerFactory;
>  import org.apache.geronimo.kernel.classloader.UnionEnumeration;
>  import org.apache.geronimo.kernel.repository.Artifact;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRule;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
>  import org.apache.geronimo.kernel.util.ClassLoaderRegistry;
> +import org.slf4j.Logger;
> +import org.slf4j.LoggerFactory;
>  
>  /**
>   * A MultiParentClassLoader is a simple extension of the URLClassLoader that simply changes the single parent class
> @@ -57,11 +58,7 @@
>  
>      private final Artifact id;
>      private final ClassLoader[] parents;
> -    private final boolean inverseClassLoading;
> -    private final String[] hiddenClasses;
> -    private final String[] nonOverridableClasses;
> -    private final String[] hiddenResources;
> -    private final String[] nonOverridableResources;
> +    private final ClassLoadingRules classLoadingRules;
>      private boolean destroyed = false;
>  
>      // I used this pattern as its temporary and with the static final we get compile time 
> @@ -102,12 +99,9 @@
>      public MultiParentClassLoader(Artifact id, URL[] urls) {
>          super(urls);
>          this.id = id;
> +        
>          parents = new ClassLoader[]{ClassLoader.getSystemClassLoader()};
> -        inverseClassLoading = false;
> -        hiddenClasses = new String[0];
> -        nonOverridableClasses = new String[0];
> -        hiddenResources = new String[0];
> -        nonOverridableResources = new String[0];
> +        classLoadingRules = new ClassLoadingRules();
>          ClassLoaderRegistry.add(this);
>      }
>  
> @@ -123,8 +117,8 @@
>          this(id, urls, new ClassLoader[]{parent});
>      }
>  
> -    public MultiParentClassLoader(Artifact id, URL[] urls, ClassLoader parent, boolean inverseClassLoading, String[] hiddenClasses, String[] nonOverridableClasses) {
> -        this(id, urls, new ClassLoader[]{parent}, inverseClassLoading, hiddenClasses, nonOverridableClasses);
> +    public MultiParentClassLoader(Artifact id, URL[] urls, ClassLoader parent, ClassLoadingRules classLoadingRules) {
> +        this(id, urls, new ClassLoader[]{parent}, classLoadingRules);
>      }
>  
>      /**
> @@ -151,32 +145,21 @@
>          super(urls);
>          this.id = id;
>          this.parents = copyParents(parents);
> -        inverseClassLoading = false;
> -        hiddenClasses = new String[0];
> -        nonOverridableClasses = new String[0];
> -        hiddenResources = new String[0];
> -        nonOverridableResources = new String[0];
> -        ClassLoaderRegistry.add(this);
> -    }
>  
> -    public MultiParentClassLoader(Artifact id, URL[] urls, ClassLoader[] parents, boolean inverseClassLoading, Collection hiddenClasses, Collection nonOverridableClasses) {
> -        this(id, urls, parents, inverseClassLoading, (String[]) hiddenClasses.toArray(new String[hiddenClasses.size()]), (String[]) nonOverridableClasses.toArray(new String[nonOverridableClasses.size()]));
> +        classLoadingRules = new ClassLoadingRules();
> +        ClassLoaderRegistry.add(this);
>      }
>  
> -    public MultiParentClassLoader(Artifact id, URL[] urls, ClassLoader[] parents, boolean inverseClassLoading, String[] hiddenClasses, String[] nonOverridableClasses) {
> +    public MultiParentClassLoader(Artifact id, URL[] urls, ClassLoader[] parents, ClassLoadingRules classLoadingRules) {
>          super(urls);
>          this.id = id;
>          this.parents = copyParents(parents);
> -        this.inverseClassLoading = inverseClassLoading;
> -        this.hiddenClasses = hiddenClasses;
> -        this.nonOverridableClasses = nonOverridableClasses;
> -        hiddenResources = toResources(hiddenClasses);
> -        nonOverridableResources = toResources(nonOverridableClasses);
> +        this.classLoadingRules = classLoadingRules;
>          ClassLoaderRegistry.add(this);
>      }
>  
>      public MultiParentClassLoader(MultiParentClassLoader source) {
> -        this(source.id, source.getURLs(), deepCopyParents(source.parents), source.inverseClassLoading, source.hiddenClasses, source.nonOverridableClasses);
> +        this(source.id, source.getURLs(), deepCopyParents(source.parents), source.classLoadingRules);
>      }
>  
>      static ClassLoader copy(ClassLoader source) {
> @@ -193,15 +176,6 @@
>          return MultiParentClassLoader.copy(this);
>      }
>  
> -    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;
> -    }
> -
>      /**
>       * Creates a named class loader as a child of the specified parents and using the specified URLStreamHandlerFactory
>       * for accessing the urls..
> @@ -215,11 +189,8 @@
>          super(urls, null, factory);
>          this.id = id;
>          this.parents = copyParents(parents);
> -        inverseClassLoading = false;
> -        hiddenClasses = new String[0];
> -        nonOverridableClasses = new String[0];
> -        hiddenResources = new String[0];
> -        nonOverridableResources = new String[0];
> +        
> +        classLoadingRules = new ClassLoadingRules();
>          ClassLoaderRegistry.add(this);
>      }
>  
> @@ -320,7 +291,7 @@
>          //
>          // if we are using inverse class loading, check local urls first
>          //
> -        if (inverseClassLoading && !isDestroyed() && !isNonOverridableClass(name)) {
> +        if (classLoadingRules.isInverseClassLoading() && !isDestroyed() && !isNonOverridableClass(name)) {
>              try {
>                  Class clazz = findClass(name);
>                  return resolveClass(clazz, resolve);
> @@ -404,7 +375,7 @@
>          //
>          // if we are using inverse class loading, check local urls first
>          //
> -        if (inverseClassLoading && !isDestroyed() && !isNonOverridableClass(name)) {
> +        if (classLoadingRules.isInverseClassLoading() && !isDestroyed() && !isNonOverridableClass(name)) {
>              try {
>                  Class clazz = findClass(name);
>                  return resolveClass(clazz, resolve);
> @@ -453,7 +424,7 @@
>       * @return
>       * @throws ClassNotFoundException
>       */
> -    protected synchronized Class<?> loadClassInternal(String name, boolean resolve, LinkedList<ClassLoader> visitedClassLoaders) throws ClassNotFoundException, MalformedURLException {
> +    protected synchronized Class<?> loadClassInternal(String name, boolean resolve, List<ClassLoader> visitedClassLoaders) throws ClassNotFoundException, MalformedURLException {
>          //
>          // Check if class is in the loaded classes cache
>          //
> @@ -500,7 +471,7 @@
>       * @return
>       * @throws ClassNotFoundException
>       */
> -    private synchronized Class<?> checkParents(String name, boolean resolve, LinkedList<ClassLoader> visitedClassLoaders) throws ClassNotFoundException {
> +    private synchronized Class<?> checkParents(String name, boolean resolve, List<ClassLoader> visitedClassLoaders) throws ClassNotFoundException {
>          for (ClassLoader parent : parents) {
>              if (!visitedClassLoaders.contains(parent)) {
>                  visitedClassLoaders.add(parent);  // Track that we've been here before
> @@ -508,6 +479,9 @@
>          	        if (parent instanceof MultiParentClassLoader) {
>          	        	Class clazz = ((MultiParentClassLoader) parent).loadClassInternal(name, resolve, visitedClassLoaders);
>          	        	if (clazz != null) return resolveClass(clazz, resolve);
> +        	        } else if (parent instanceof ChildrenConfigurationClassLoader) {
> +                        Class clazz = ((ChildrenConfigurationClassLoader) parent).loadClass(name, visitedClassLoaders);
> +                        if (clazz != null) return resolveClass(clazz, resolve);
>          	        } else {
>          	        	return parent.loadClass(name);
>          	        }
> @@ -523,21 +497,13 @@
>      }
>  
>      private boolean isNonOverridableClass(String name) {
> -        for (String nonOverridableClass : nonOverridableClasses) {
> -            if (name.startsWith(nonOverridableClass)) {
> -                return true;
> -            }
> -        }
> -        return false;
> +        ClassLoadingRule nonOverrideableRule = classLoadingRules.getNonOverrideableRule();
> +        return nonOverrideableRule.isFilteredClass(name);
>      }
>  
>      private boolean isHiddenClass(String name) {
> -        for (String hiddenClass : hiddenClasses) {
> -            if (name.startsWith(hiddenClass)) {
> -                return true;
> -            }
> -        }
> -        return false;
> +        ClassLoadingRule hiddenRule = classLoadingRules.getHiddenRule();
> +        return hiddenRule.isFilteredClass(name);
>      }
>  
>      private Class resolveClass(Class clazz, boolean resolve) {
> @@ -555,7 +521,7 @@
>          //
>          // if we are using inverse class loading, check local urls first
>          //
> -        if (inverseClassLoading && !isDestroyed() && !isNonOverridableResource(name)) {
> +        if (classLoadingRules.isInverseClassLoading() && !isDestroyed() && !isNonOverridableResource(name)) {
>              URL url = findResource(name);
>              if (url != null) {
>                  return url;
> @@ -606,7 +572,7 @@
>              return;
>          }
>          knownClassloaders.add(this);
> -        if (inverseClassLoading && !isNonOverridableResource(name)) {
> +        if (classLoadingRules.isInverseClassLoading() && !isNonOverridableResource(name)) {
>              enumerations.add(internalfindResources(name));
>          }
>          if (!isHiddenResource(name)) {
> @@ -621,7 +587,7 @@
>                  }
>              }
>          }
> -        if (!inverseClassLoading) {
> +        if (!classLoadingRules.isInverseClassLoading()) {
>              enumerations.add(internalfindResources(name));
>          }
>      }
> @@ -631,21 +597,13 @@
>      }
>  
>      private boolean isNonOverridableResource(String name) {
> -        for (String nonOverridableResource : nonOverridableResources) {
> -            if (name.startsWith(nonOverridableResource)) {
> -                return true;
> -            }
> -        }
> -        return false;
> +        ClassLoadingRule nonOverrideableRule = classLoadingRules.getNonOverrideableRule();
> +        return nonOverrideableRule.isFilteredResource(name);
>      }
>  
>      private boolean isHiddenResource(String name) {
> -        for (String hiddenResource : hiddenResources) {
> -            if (name.startsWith(hiddenResource)) {
> -                return true;
> -            }
> -        }
> -        return false;
> +        ClassLoadingRule hiddenRule = classLoadingRules.getHiddenRule();
> +        return hiddenRule.isFilteredResource(name);
>      }
>  
>      public String toString() {
> 
> Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/ClassLoadingRule.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/ClassLoadingRule.java?rev=712326&view=auto
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/ClassLoadingRule.java (added)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/ClassLoadingRule.java Fri Nov  7 16:40:08 2008
> @@ -0,0 +1,85 @@
> +/*
> + * 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.geronimo.kernel.repository;
> +
> +import java.io.Serializable;
> +import java.util.HashSet;
> +import java.util.Set;
> +
> +/**
> + *
> + * @version $Rev:$ $Date:$
> + */
> +public class ClassLoadingRule implements Serializable {
> +    private final Set<String> classPrefixes;
> +    private final Set<String> resourcePrefixes;
> +    
> +    public ClassLoadingRule() {
> +        classPrefixes = new HashSet<String>();
> +        resourcePrefixes = new HashSet<String>();
> +    }
> +
> +    public Set<String> getClassPrefixes() {
> +        return classPrefixes;
> +    }
> +
> +    public boolean isFilteredClass(String name) {
> +        return isMatching(classPrefixes, name);
> +    }
> +    
> +    public boolean isFilteredResource(String name) {
> +        return isMatching(resourcePrefixes, name);
> +    }
> +    
> +    public void addClassPrefixes(Set<String> classPrefixes) {
> +        this.classPrefixes.addAll(classPrefixes);
> +
> +        Set<String> resources = toResources(classPrefixes);
> +        resourcePrefixes.addAll(resources);
> +    }
> +
> +    public void setClassPrefixes(Set<String> classPrefixes) {
> +        this.classPrefixes.clear();
> +        resourcePrefixes.clear();
> +        addClassPrefixes(classPrefixes);
> +    }
> +    
> +    public void merge(ClassLoadingRule classLoadingRuleToMerge) {
> +        addClassPrefixes(classLoadingRuleToMerge.classPrefixes);
> +    }
> +
> +    protected Set<String> toResources(Set<String> classPrefixes) {
> +        Set<String> resources = new HashSet<String>();
> +        for (String className : classPrefixes) {
> +            resources.add(className.replace('.', '/'));
> +        }
> +        return resources;
> +    }
> +    
> +    protected boolean isMatching(Set<String> prefixes, String name) {
> +        for (String prefix : prefixes) {
> +            if (name.startsWith(prefix)) {
> +                return true;
> +            }
> +        }
> +        return false;
> +    }
> +
> +}
> \ No newline at end of file
> 
> Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/ClassLoadingRules.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/ClassLoadingRules.java?rev=712326&view=auto
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/ClassLoadingRules.java (added)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/ClassLoadingRules.java Fri Nov  7 16:40:08 2008
> @@ -0,0 +1,72 @@
> +/*
> + * 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.geronimo.kernel.repository;
> +
> +import java.io.Serializable;
> +
> +
> +/**
> + *
> + * @version $Rev:$ $Date:$
> + */
> +public class ClassLoadingRules implements Serializable {
> +    private final ClassLoadingRule hiddenRule;
> +    private final ClassLoadingRule nonOverrideableRule;
> +    private final ClassLoadingRule privateRule;
> +    private boolean inverseClassLoading;
> +
> +    public ClassLoadingRules() {
> +        hiddenRule = new ClassLoadingRule();
> +        nonOverrideableRule = new ClassLoadingRule();
> +        privateRule = new ClassLoadingRule();
> +    }
> +
> +    public ClassLoadingRule getHiddenRule() {
> +        return hiddenRule;
> +    }
> +
> +    public ClassLoadingRule getNonOverrideableRule() {
> +        return nonOverrideableRule;
> +    }
> +
> +    public ClassLoadingRule getPrivateRule() {
> +        return privateRule;
> +    }
> +
> +    public boolean isInverseClassLoading() {
> +        return inverseClassLoading;
> +    }
> +
> +    public void setInverseClassLoading(boolean inverseClassLoading) {
> +        this.inverseClassLoading = inverseClassLoading;
> +    }
> +
> +    public void merge(ClassLoadingRules classLoadingRulesToMerge) {
> +        if (inverseClassLoading) {
> +            return;
> +        }
> +        inverseClassLoading = classLoadingRulesToMerge.inverseClassLoading;
> +        
> +        hiddenRule.merge(classLoadingRulesToMerge.hiddenRule);
> +        nonOverrideableRule.merge(classLoadingRulesToMerge.nonOverrideableRule);
> +        privateRule.merge(classLoadingRulesToMerge.privateRule);
> +    }
> +
> +}
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/DefaultArtifactResolver.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/DefaultArtifactResolver.java?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/DefaultArtifactResolver.java (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/DefaultArtifactResolver.java Fri Nov  7 16:40:08 2008
> @@ -179,7 +179,7 @@
>              }
>  
>              Environment environment = configuration.getEnvironment();
> -            if (environment.isInverseClassLoading()) {
> +            if (environment.getClassLoadingRules().isInverseClassLoading()) {
>                  // Search dependencies of the configuration before searching the parents
>                  Artifact artifact = getArtifactVersion(configuration.getDependencies(), working);
>                  if (artifact != null) {
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/Environment.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/Environment.java?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/Environment.java (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/repository/Environment.java Fri Nov  7 16:40:08 2008
> @@ -18,14 +18,12 @@
>  package org.apache.geronimo.kernel.repository;
>  
>  import java.io.Serializable;
> +import java.util.ArrayList;
>  import java.util.Collection;
> -import java.util.HashSet;
> -import java.util.LinkedHashSet;
> -import java.util.Set;
> -import java.util.List;
>  import java.util.Collections;
> -import java.util.ArrayList;
>  import java.util.Iterator;
> +import java.util.LinkedHashSet;
> +import java.util.List;
>  
>  /**
>   * holds the data from the EnvironmentType xml while it is being resolved, transitively closed, etc.
> @@ -36,29 +34,25 @@
>      private static final long serialVersionUID = 7075760873629376317L;
>  
>      private Artifact configId;
> -
>      private final LinkedHashSet dependencies = new LinkedHashSet();
> -
> -    private final Set hiddenClasses = new HashSet();
> -    private final Set nonOverrideableClasses = new HashSet();
> -
> -    private boolean inverseClassLoading;
> +    private final ClassLoadingRules classLoadingRules;
>      private boolean suppressDefaultEnvironment;
>  
>      public Environment() {
> +        classLoadingRules = new ClassLoadingRules();
>      }
>  
>      public Environment(Artifact configId) {
>          this.configId = configId;
> +
> +        classLoadingRules = new ClassLoadingRules();
>      }
>  
>      public Environment(Environment environment) {
> -        this.configId = environment.getConfigId();
> -        this.dependencies.addAll(environment.dependencies);
> -        this.hiddenClasses.addAll(environment.getHiddenClasses());
> -        this.nonOverrideableClasses.addAll(environment.getNonOverrideableClasses());
> -        this.inverseClassLoading = environment.isInverseClassLoading();
> -        this.suppressDefaultEnvironment = environment.isSuppressDefaultEnvironment();
> +        configId = environment.getConfigId();
> +        dependencies.addAll(environment.dependencies);
> +        suppressDefaultEnvironment = environment.isSuppressDefaultEnvironment();
> +        classLoadingRules = environment.classLoadingRules;
>      }
>  
>      public Artifact getConfigId() {
> @@ -100,46 +94,8 @@
>          addDependencies(dependencies);
>      }
>  
> -    /**
> -     * todo: I should be documented so it's not completely unclear what kind of
> -     * elements I hold.
> -     */
> -    public Set getHiddenClasses() {
> -        return hiddenClasses;
> -    }
> -
> -    public void addHiddenClasses(Collection hiddenClasses) {
> -        this.hiddenClasses.addAll(hiddenClasses);
> -    }
> -
> -    public void setHiddenClasses(Collection hiddenClasses) {
> -        this.hiddenClasses.clear();
> -        addHiddenClasses(hiddenClasses);
> -    }
> -
> -    /**
> -     * todo: I should be documented so it's not completely unclear what kind of
> -     * elements I hold.
> -     */
> -    public Set getNonOverrideableClasses() {
> -        return nonOverrideableClasses;
> -    }
> -
> -    public void addNonOverrideableClasses(Collection nonOverrideableClasses) {
> -        this.nonOverrideableClasses.addAll(nonOverrideableClasses);
> -    }
> -
> -    public void setNonOverrideableClasses(Collection nonOverrideableClasses) {
> -        this.nonOverrideableClasses.clear();
> -        addNonOverrideableClasses(nonOverrideableClasses);
> -    }
> -
> -    public boolean isInverseClassLoading() {
> -        return inverseClassLoading;
> -    }
> -
> -    public void setInverseClassLoading(boolean inverseClassLoading) {
> -        this.inverseClassLoading = inverseClassLoading;
> +    public ClassLoadingRules getClassLoadingRules() {
> +        return classLoadingRules;
>      }
>  
>      public boolean isSuppressDefaultEnvironment() {
> 
> Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/config/ChildrenConfigurationClassLoaderTest.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/config/ChildrenConfigurationClassLoaderTest.java?rev=712326&view=auto
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/config/ChildrenConfigurationClassLoaderTest.java (added)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/config/ChildrenConfigurationClassLoaderTest.java Fri Nov  7 16:40:08 2008
> @@ -0,0 +1,78 @@
> +/*
> + * 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.geronimo.kernel.config;
> +
> +import java.util.Collections;
> +
> +import org.apache.geronimo.kernel.repository.ClassLoadingRule;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
> +
> +import junit.framework.TestCase;
> +
> +/**
> + *
> + * @version $Rev:$ $Date:$
> + */
> +public class ChildrenConfigurationClassLoaderTest extends TestCase {
> +
> +    private String privateResourceName;
> +    private String privateResourceClass;
> +    private ChildrenConfigurationClassLoader classLoader;
> +    private ClassLoadingRules rules;
> +
> +    @Override
> +    protected void setUp() throws Exception {
> +        rules = new ClassLoadingRules();
> +        privateResourceClass = ChildrenConfigurationClassLoaderTest.class.getName();
> +        privateResourceName = privateResourceClass.replace(".", "/") + ".class";
> +
> +        classLoader = new ChildrenConfigurationClassLoader(ChildrenConfigurationClassLoaderTest.class.getClassLoader(), rules);
> +    }
> +
> +    public void testLoadClassThrowsCNFEForHiddenClass() throws Exception {
> +        classLoader.loadClass(privateResourceClass);
> +
> +        addPrivateConfiguration();
> +
> +        try {
> +            classLoader.loadClass(privateResourceClass);
> +            fail();
> +        } catch (ClassNotFoundException e) {
> +        }
> +    }
> +    
> +    public void testGetResourceReturnsNullForHiddenClass() throws Exception {
> +        assertNotNull(classLoader.getResource(privateResourceName));
> +        addPrivateConfiguration();
> +        assertNull(classLoader.getResource(privateResourceName));
> +    }
> +    
> +    public void testGetResourcesReturnsEmptyEnumForHiddenClass() throws Exception {
> +        assertTrue(classLoader.getResources(privateResourceName).hasMoreElements());
> +        addPrivateConfiguration();
> +        assertFalse(classLoader.getResources(privateResourceName).hasMoreElements());
> +    }
> +
> +    private void addPrivateConfiguration() {
> +        ClassLoadingRule rule = rules.getPrivateRule();
> +        rule.addClassPrefixes(Collections.singleton(privateResourceClass));
> +    }
> +
> +}
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/config/MultiParentClassLoaderTest.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/config/MultiParentClassLoaderTest.java?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/config/MultiParentClassLoaderTest.java (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/config/MultiParentClassLoaderTest.java Fri Nov  7 16:40:08 2008
> @@ -26,6 +26,7 @@
>  import java.util.jar.JarFile;
>  import java.util.jar.JarOutputStream;
>  import java.util.jar.JarEntry;
> +import java.util.Collections;
>  import java.util.Enumeration;
>  
>  import junit.framework.TestCase;
> @@ -35,6 +36,8 @@
>  import net.sf.cglib.core.Predicate;
>  import net.sf.cglib.core.DefaultGeneratorStrategy;
>  import org.apache.geronimo.kernel.repository.Artifact;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRule;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
>  
>  /**
>   * @version $Rev$ $Date$
> @@ -141,7 +144,9 @@
>          Class clazz = cl.loadClass(CLASS_NAME);
>          assertSame(parentCl, clazz.getClassLoader());
>  
> -        cl = new MultiParentClassLoader(NAME, new URL[]{myJar.toURL()}, parentCl, true, new String[0], new String[0]);
> +        ClassLoadingRules classLoadingRules = new ClassLoadingRules();
> +        classLoadingRules.setInverseClassLoading(true);
> +        cl = new MultiParentClassLoader(NAME, new URL[]{myJar.toURL()}, parentCl, classLoadingRules);
>          clazz = cl.loadClass(CLASS_NAME);
>          assertSame(cl, clazz.getClassLoader());
>      }
> @@ -154,7 +159,10 @@
>          Class clazz = cl.loadClass(CLASS_NAME);
>          assertSame(parentCl, clazz.getClassLoader());
>  
> -        cl = new MultiParentClassLoader(NAME, new URL[]{myJar.toURL()}, parentCl, false, new String[] {CLASS_NAME}, new String[0]);
> +        ClassLoadingRules classLoadingRules = new ClassLoadingRules();
> +        ClassLoadingRule classLoadingRule = classLoadingRules.getHiddenRule();
> +        classLoadingRule.addClassPrefixes(Collections.singleton(CLASS_NAME));
> +        cl = new MultiParentClassLoader(NAME, new URL[]{myJar.toURL()}, parentCl, classLoadingRules);
>          clazz = cl.loadClass(CLASS_NAME);
>          assertSame(cl, clazz.getClassLoader());
>      }
> @@ -167,7 +175,11 @@
>          Class clazz = cl.loadClass(CLASS_NAME);
>          assertSame(parentCl, clazz.getClassLoader());
>  
> -        cl = new MultiParentClassLoader(NAME, new URL[]{myJar.toURL()}, parentCl, true, new String[0], new String[] {CLASS_NAME});
> +        ClassLoadingRules classLoadingRules = new ClassLoadingRules();
> +        classLoadingRules.setInverseClassLoading(true);
> +        ClassLoadingRule classLoadingRule = classLoadingRules.getNonOverrideableRule();
> +        classLoadingRule.addClassPrefixes(Collections.singleton(CLASS_NAME));
> +        cl = new MultiParentClassLoader(NAME, new URL[]{myJar.toURL()}, parentCl, classLoadingRules);
>          clazz = cl.loadClass(CLASS_NAME);
>          assertSame(parentCl, clazz.getClassLoader());
>      }
> 
> Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/repository/ClassLoadingRuleTest.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/repository/ClassLoadingRuleTest.java?rev=712326&view=auto
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/repository/ClassLoadingRuleTest.java (added)
> +++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/test/java/org/apache/geronimo/kernel/repository/ClassLoadingRuleTest.java Fri Nov  7 16:40:08 2008
> @@ -0,0 +1,84 @@
> +/*
> + * 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.geronimo.kernel.repository;
> +
> +import java.util.Collections;
> +import java.util.Set;
> +
> +import junit.framework.TestCase;
> +
> +/**
> + *
> + * @version $Rev:$ $Date:$
> + */
> +public class ClassLoadingRuleTest extends TestCase {
> +    private static final String FILTERED_PREFIX = "org.apache.geronimo";
> +    private static final String FILTERED_RESOURCE_PREFIX = "org/apache/geronimo";
> +
> +    private ClassLoadingRule rule;
> +
> +    @Override
> +    protected void setUp() throws Exception {
> +        rule = new ClassLoadingRule();
> +        Set<String> filter = Collections.singleton(FILTERED_PREFIX);
> +        rule.addClassPrefixes(filter);
> +    }
> +    
> +    public void testIsFilteredClass() throws Exception {
> +        assertTrue(rule.isFilteredClass(FILTERED_PREFIX + ".mock"));
> +    }
> +    
> +    public void testIsNotFilteredClass() throws Exception {
> +        assertFalse(rule.isFilteredClass("mock"));
> +    }
> +    
> +    public void testIsFilteredResource() throws Exception {
> +        assertTrue(rule.isFilteredResource(FILTERED_RESOURCE_PREFIX + "/mock"));
> +    }
> +    
> +    public void testIsNotFilteredResource() throws Exception {
> +        assertFalse(rule.isFilteredResource("mock"));
> +    }
> +    
> +    public void testMerge() throws Exception {
> +        ClassLoadingRule ruleToMerge = new ClassLoadingRule();
> +        String mergedFilteredPrefix = "geronimo";
> +        Set<String> filter = Collections.singleton(mergedFilteredPrefix);
> +        ruleToMerge.addClassPrefixes(filter);
> +
> +        rule.merge(ruleToMerge);
> +        
> +        assertTrue(rule.isFilteredClass(mergedFilteredPrefix + ".mock"));
> +        assertTrue(rule.isFilteredResource(mergedFilteredPrefix + "/mock"));
> +    }
> +    
> +    public void testSetClassPrefixResetState() throws Exception {
> +        String newFilteredPrefix = "geronimo";
> +        Set<String> filter = Collections.singleton(newFilteredPrefix);
> +        rule.setClassPrefixes(filter);
> +        
> +        assertTrue(rule.isFilteredClass(newFilteredPrefix + ".mock"));
> +        assertTrue(rule.isFilteredResource(newFilteredPrefix + "/mock"));
> +
> +        assertFalse(rule.isFilteredClass(FILTERED_PREFIX + ".mock"));
> +        assertFalse(rule.isFilteredResource(FILTERED_PREFIX + "/mock"));
> +    }
> +    
> +}
> 
> Added: geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/java/org/apache/geronimo/deployment/service/ClassLoadingRulesUtil.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/java/org/apache/geronimo/deployment/service/ClassLoadingRulesUtil.java?rev=712326&view=auto
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/java/org/apache/geronimo/deployment/service/ClassLoadingRulesUtil.java (added)
> +++ geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/java/org/apache/geronimo/deployment/service/ClassLoadingRulesUtil.java Fri Nov  7 16:40:08 2008
> @@ -0,0 +1,70 @@
> +/*
> + * 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.geronimo.deployment.service;
> +
> +import java.util.HashSet;
> +import java.util.Set;
> +
> +import org.apache.geronimo.deployment.xbeans.ClassFilterType;
> +import org.apache.geronimo.deployment.xbeans.EnvironmentType;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRule;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
> +
> +/**
> + *
> + * @version $Rev:$ $Date:$
> + */
> +public final class ClassLoadingRulesUtil {
> +
> +    private ClassLoadingRulesUtil() {
> +    }
> +
> +    public static void configureRules(ClassLoadingRules classLoadingRules, EnvironmentType environmentType) {
> +        classLoadingRules.setInverseClassLoading(environmentType.isSetInverseClassloading());
> +        
> +        if (null != environmentType.getHiddenClasses()) {
> +            ClassLoadingRule hiddenRule = classLoadingRules.getHiddenRule();
> +            hiddenRule.setClassPrefixes(toFilters(environmentType.getHiddenClasses()));
> +        }
> +        
> +        if (null != environmentType.getNonOverridableClasses()) {
> +            ClassLoadingRule nonOverrideableRule = classLoadingRules.getNonOverrideableRule();
> +            nonOverrideableRule.setClassPrefixes(toFilters(environmentType.getNonOverridableClasses()));
> +        }
> +        
> +        if (null != environmentType.getPrivateClasses()) {
> +            ClassLoadingRule privateRule = classLoadingRules.getPrivateRule();
> +            privateRule.setClassPrefixes(toFilters(environmentType.getPrivateClasses()));
> +        }
> +    }
> +   
> +    private static Set<String> toFilters(ClassFilterType filterType) {
> +        Set<String> filters = new HashSet<String>();
> +        if (null != filterType) {
> +            String[] filterArray = filterType.getFilterArray();
> +            for (String filter : filterArray) {
> +                filter = filter.trim();
> +                filters.add(filter);
> +            }
> +        }
> +        return filters;
> +    }
> +    
> +}
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/java/org/apache/geronimo/deployment/service/EnvironmentBuilder.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/java/org/apache/geronimo/deployment/service/EnvironmentBuilder.java?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/java/org/apache/geronimo/deployment/service/EnvironmentBuilder.java (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/java/org/apache/geronimo/deployment/service/EnvironmentBuilder.java Fri Nov  7 16:40:08 2008
> @@ -38,6 +38,8 @@
>  import org.apache.geronimo.deployment.xbeans.ImportType;
>  import org.apache.geronimo.deployment.xbeans.DependencyType;
>  import org.apache.geronimo.kernel.repository.Artifact;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRule;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
>  import org.apache.geronimo.kernel.repository.Dependency;
>  import org.apache.geronimo.kernel.repository.Environment;
>  import org.apache.xmlbeans.XmlException;
> @@ -63,10 +65,9 @@
>                  LinkedHashSet dependencies = toDependencies(dependencyArray);
>                  environment.setDependencies(dependencies);
>              }
> -            environment.setInverseClassLoading(environmentType.isSetInverseClassloading());
>              environment.setSuppressDefaultEnvironment(environmentType.isSetSuppressDefaultEnvironment());
> -            environment.setHiddenClasses(toFilters(environmentType.getHiddenClasses()));
> -            environment.setNonOverrideableClasses(toFilters(environmentType.getNonOverridableClasses()));
> +            
> +            ClassLoadingRulesUtil.configureRules(environment.getClassLoadingRules(), environmentType);
>          }
>  
>          return environment;
> @@ -79,10 +80,11 @@
>                  environment.setConfigId(additionalEnvironment.getConfigId());
>              }
>              environment.addDependencies(additionalEnvironment.getDependencies());
> -            environment.setInverseClassLoading(environment.isInverseClassLoading() || additionalEnvironment.isInverseClassLoading());
>              environment.setSuppressDefaultEnvironment(environment.isSuppressDefaultEnvironment() || additionalEnvironment.isSuppressDefaultEnvironment());
> -            environment.addHiddenClasses(additionalEnvironment.getHiddenClasses());
> -            environment.addNonOverrideableClasses(additionalEnvironment.getNonOverrideableClasses());
> +            
> +            ClassLoadingRules classLoadingRules = environment.getClassLoadingRules();
> +            ClassLoadingRules additionalClassLoadingRules = additionalEnvironment.getClassLoadingRules();
> +            classLoadingRules.merge(additionalClassLoadingRules);
>          }
>      }
>  
> @@ -105,14 +107,25 @@
>          DependencyType[] dependencyTypes = (DependencyType[]) dependencies.toArray(new DependencyType[dependencies.size()]);
>          DependenciesType dependenciesType = environmentType.addNewDependencies();
>          dependenciesType.setDependencyArray(dependencyTypes);
> -        if (environment.isInverseClassLoading()) {
> +        
> +        ClassLoadingRules classLoadingRules = environment.getClassLoadingRules();
> +        if (classLoadingRules.isInverseClassLoading()) {
>              environmentType.addNewInverseClassloading();
>          }
> +        
>          if (environment.isSuppressDefaultEnvironment()) {
>              environmentType.addNewSuppressDefaultEnvironment();
>          }
> -        environmentType.setHiddenClasses(toFilterType(environment.getHiddenClasses()));
> -        environmentType.setNonOverridableClasses(toFilterType(environment.getNonOverrideableClasses()));
> +        
> +        ClassLoadingRule classLoadingRule = classLoadingRules.getHiddenRule();
> +        environmentType.setHiddenClasses(toFilterType(classLoadingRule.getClassPrefixes()));
> +        
> +        classLoadingRule = classLoadingRules.getNonOverrideableRule();
> +        environmentType.setNonOverridableClasses(toFilterType(classLoadingRule.getClassPrefixes()));
> +
> +        classLoadingRule = classLoadingRules.getPrivateRule();
> +        environmentType.setPrivateClasses(toFilterType(classLoadingRule.getClassPrefixes()));
> +        
>          return environmentType;
>      }
>  
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/xsd/geronimo-module-1.2.xsd
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/xsd/geronimo-module-1.2.xsd?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/xsd/geronimo-module-1.2.xsd (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-service-builder/src/main/xsd/geronimo-module-1.2.xsd Fri Nov  7 16:40:08 2008
> @@ -204,6 +204,21 @@
>                      </xs:documentation>
>                  </xs:annotation>
>              </xs:element>
> +            <xs:element name="private-classes"
> +                type="sys:classFilterType" minOccurs="0">
> +                <xs:annotation>
> +                    <xs:documentation>
> +                        A list of classes which will only be loaded from the
> +                        ClassLoader of this module or from parent ClassLoaders.
> +                        
> +                        This is used to prevent children configurations to see
> +                        specific classes from its parents. The same effect can
> +                        be achieved by using hidden-classes. However,
> +                        private-classes is the preferred approach to hide 
> +                        specific classes from all children configurations. 
> +                    </xs:documentation>
> +                </xs:annotation>
> +            </xs:element>
>              <xs:element name="inverse-classloading" type="sys:emptyType"
>                  minOccurs="0">
>                  <xs:annotation>
> 
> Added: geronimo/server/trunk/framework/modules/geronimo-service-builder/src/test/java/org/apache/geronimo/deployment/service/ClassLoadingRulesUtilTest.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-service-builder/src/test/java/org/apache/geronimo/deployment/service/ClassLoadingRulesUtilTest.java?rev=712326&view=auto
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-service-builder/src/test/java/org/apache/geronimo/deployment/service/ClassLoadingRulesUtilTest.java (added)
> +++ geronimo/server/trunk/framework/modules/geronimo-service-builder/src/test/java/org/apache/geronimo/deployment/service/ClassLoadingRulesUtilTest.java Fri Nov  7 16:40:08 2008
> @@ -0,0 +1,66 @@
> +/*
> + * 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.geronimo.deployment.service;
> +
> +import java.util.Set;
> +
> +import junit.framework.TestCase;
> +
> +import org.apache.geronimo.deployment.xbeans.ClassFilterType;
> +import org.apache.geronimo.deployment.xbeans.EmptyType;
> +import org.apache.geronimo.deployment.xbeans.EnvironmentType;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRule;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
> +
> +/**
> + *
> + * @version $Rev:$ $Date:$
> + */
> +public class ClassLoadingRulesUtilTest extends TestCase {
> +
> +    public void testConfiguration() throws Exception {
> +        EnvironmentType environmentType = EnvironmentType.Factory.newInstance();
> +        environmentType.setInverseClassloading(EmptyType.Factory.newInstance());
> +        environmentType.setHiddenClasses(newFilter("hidden"));
> +        environmentType.setNonOverridableClasses(newFilter("nonOverrideable"));
> +        environmentType.setPrivateClasses(newFilter("private"));
> +        
> +        ClassLoadingRules classLoadingRules = new ClassLoadingRules();
> +        ClassLoadingRulesUtil.configureRules(classLoadingRules, environmentType);
> +        
> +        assertTrue(classLoadingRules.isInverseClassLoading());
> +        assertPrefix(classLoadingRules.getHiddenRule(), "hidden");
> +        assertPrefix(classLoadingRules.getNonOverrideableRule(), "nonOverrideable");
> +        assertPrefix(classLoadingRules.getPrivateRule(), "private");
> +    }
> +
> +    private void assertPrefix(ClassLoadingRule classLoadingRule, String filter) {
> +        Set<String> classPrefixes = classLoadingRule.getClassPrefixes();
> +        assertEquals(1, classPrefixes.size());
> +        assertTrue(classPrefixes.contains(filter));
> +    }
> +
> +    private ClassFilterType newFilter(String filter) {
> +        ClassFilterType hiddenClasses = ClassFilterType.Factory.newInstance();
> +        hiddenClasses.addFilter(filter);
> +        return hiddenClasses;
> +    }
> +    
> +}
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/appclient_dep_1_result.xml
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/appclient_dep_1_result.xml?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/appclient_dep_1_result.xml (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/appclient_dep_1_result.xml Fri Nov  7 16:40:08 2008
> @@ -44,6 +44,7 @@
>      </dep:dependencies>
>      <dep:hidden-classes/>
>      <dep:non-overridable-classes/>
> +    <dep:private-classes/>
>    </dep:environment>
>    <module>
>      <java>appclient_dep_resref_single_client.jar</java>
> @@ -89,6 +90,7 @@
>          </dep:dependencies>
>          <dep:hidden-classes/>
>          <dep:non-overridable-classes/>
> +        <dep:private-classes/>
>        </dep:client-environment>
>        <dep:server-environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2">
>          <dep:moduleId>
> @@ -100,6 +102,7 @@
>          <dep:dependencies/>
>          <dep:hidden-classes/>
>          <dep:non-overridable-classes/>
> +        <dep:private-classes/>
>        </dep:server-environment>
>        <resource-ref xmlns="http://geronimo.apache.org/xml/ns/naming-1.2">
>          <ref-name>url/URL</ref-name>
> @@ -126,6 +129,7 @@
>              <dep:dependencies/>
>              <dep:hidden-classes/>
>              <dep:non-overridable-classes/>
> +            <dep:private-classes/>
>              <dep:suppress-default-environment/>
>            </dep:environment>
>            <resourceadapter>
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/appclient_ejb_1_result.xml
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/appclient_ejb_1_result.xml?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/appclient_ejb_1_result.xml (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/appclient_ejb_1_result.xml Fri Nov  7 16:40:08 2008
> @@ -32,6 +32,7 @@
>      </dep:dependencies>
>      <dep:hidden-classes/>
>      <dep:non-overridable-classes/>
> +    <dep:private-classes/>
>    </dep:environment>
>    <module>
>      <ejb>appclient_ejb_1_ejb.jar</ejb>
> @@ -46,6 +47,7 @@
>          <dep:dependencies/>
>          <dep:hidden-classes/>
>          <dep:non-overridable-classes/>
> +        <dep:private-classes/>
>        </dep:environment>
>        <cmp-connection-factory>
>          <resource-link>jdbc/DB1</resource-link>
> @@ -90,6 +92,7 @@
>          </dep:dependencies>
>          <dep:hidden-classes/>
>          <dep:non-overridable-classes/>
> +        <dep:private-classes/>
>        </dep:client-environment>
>        <dep:server-environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2">
>          <dep:moduleId>
> @@ -101,6 +104,7 @@
>          <dep:dependencies/>
>          <dep:hidden-classes/>
>          <dep:non-overridable-classes/>
> +        <dep:private-classes/>
>        </dep:server-environment>
>      </application-client>
>    </module>
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/assembly_1_result.xml
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/assembly_1_result.xml?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/assembly_1_result.xml (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/assembly_1_result.xml Fri Nov  7 16:40:08 2008
> @@ -34,6 +34,7 @@
>          </dep:dependencies>
>          <dep:hidden-classes/>
>          <dep:non-overridable-classes/>
> +        <dep:private-classes/>
>      </dep:environment>
>      <module>
>          <java>assembly_compat_standalone_jar_compat12_13_client.jar</java>
> @@ -55,6 +56,7 @@
>                  </dep:dependencies>
>                  <dep:hidden-classes/>
>                  <dep:non-overridable-classes/>
> +                <dep:private-classes/>
>              </dep:client-environment>
>              <dep:server-environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2">
>                  <dep:moduleId>
> @@ -66,6 +68,7 @@
>                  <dep:dependencies/>
>                  <dep:hidden-classes/>
>                  <dep:non-overridable-classes/>
> +                <dep:private-classes/>
>              </dep:server-environment>
>              <ejb-ref>
>                  <ref-name>ejb/TestBean</ref-name>
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/gbean_1_result.xml
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/gbean_1_result.xml?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/gbean_1_result.xml (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/gbean_1_result.xml Fri Nov  7 16:40:08 2008
> @@ -34,6 +34,7 @@
>      </dep:dependencies>
>      <dep:hidden-classes/>
>      <dep:non-overridable-classes/>
> +    <dep:private-classes/>
>    </dep:environment>
>    <gbean name="hello-realm" class="org.apache.geronimo.security.realm.GenericSecurityRealm">
>      <attribute name="realmName">hello-realm</attribute>
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/servlet_1_result.xml
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/servlet_1_result.xml?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/servlet_1_result.xml (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/servlet_1_result.xml Fri Nov  7 16:40:08 2008
> @@ -32,6 +32,7 @@
>      </dep:dependencies>
>      <dep:hidden-classes/>
>      <dep:non-overridable-classes/>
> +    <dep:private-classes/>
>    </dep:environment>
>    <module>
>      <web>servlet_deploy_ejblink_single_web.war</web>
> @@ -46,6 +47,7 @@
>          <dep:dependencies/>
>          <dep:hidden-classes/>
>          <dep:non-overridable-classes/>
> +        <dep:private-classes/>
>        </dep:environment>
>        <ejb-ref>
>          <ref-name>ejb/StatelessBean_ExternalJAR</ref-name>
> @@ -66,6 +68,7 @@
>          <dep:dependencies/>
>          <dep:hidden-classes/>
>          <dep:non-overridable-classes/>
> +        <dep:private-classes/>
>        </dep:environment>
>        <!--YOU MUST INSERT THE ELEMENT <inverse-classloading/> INTO THE ENVIRONMENT ELEMENT FOR THIS MODULE-->
>        <ejb-ref>
> @@ -87,6 +90,7 @@
>            <dep:dependencies/>
>            <dep:hidden-classes/>
>            <dep:non-overridable-classes/>
> +          <dep:private-classes/>
>          </dep:environment>
>        </web-app>
>      </module>
> @@ -103,6 +107,7 @@
>            <dep:dependencies/>
>            <dep:hidden-classes/>
>            <dep:non-overridable-classes/>
> +          <dep:private-classes/>
>          </dep:environment>
>          <!--YOU MUST INSERT THE ELEMENT <inverse-classloading/> INTO THE ENVIRONMENT ELEMENT FOR THIS MODULE-->
>        </web-app>
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/transport_1_result.xml
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/transport_1_result.xml?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/transport_1_result.xml (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/transport_1_result.xml Fri Nov  7 16:40:08 2008
> @@ -34,6 +34,7 @@
>      </dep:dependencies>
>      <dep:hidden-classes/>
>      <dep:non-overridable-classes/>
> +    <dep:private-classes/>
>    </dep:environment>
>    <module>
>      <java>transport_1_client.jar</java>
> @@ -55,6 +56,7 @@
>          </dep:dependencies>
>          <dep:hidden-classes/>
>          <dep:non-overridable-classes/>
> +        <dep:private-classes/>
>        </dep:client-environment>
>        <dep:server-environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2">
>          <dep:moduleId>
> @@ -66,6 +68,7 @@
>          <dep:dependencies/>
>          <dep:hidden-classes/>
>          <dep:non-overridable-classes/>
> +        <dep:private-classes/>
>        </dep:server-environment>
>        <ejb-ref>
>          <ref-name>ejb/EJBVehicle</ref-name>
> 
> Modified: geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/transport_2_result.xml
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/transport_2_result.xml?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/transport_2_result.xml (original)
> +++ geronimo/server/trunk/framework/modules/geronimo-upgrade/src/test/resources/transport_2_result.xml Fri Nov  7 16:40:08 2008
> @@ -34,6 +34,7 @@
>      </dep:dependencies>
>      <dep:hidden-classes/>
>      <dep:non-overridable-classes/>
> +    <dep:private-classes/>
>    </dep:environment>
>  </application>
>          
> 
> Modified: geronimo/server/trunk/plugins/jetty/geronimo-jetty6/src/test/java/org/apache/geronimo/jetty6/ClassLoaderTest.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/jetty/geronimo-jetty6/src/test/java/org/apache/geronimo/jetty6/ClassLoaderTest.java?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/plugins/jetty/geronimo-jetty6/src/test/java/org/apache/geronimo/jetty6/ClassLoaderTest.java (original)
> +++ geronimo/server/trunk/plugins/jetty/geronimo-jetty6/src/test/java/org/apache/geronimo/jetty6/ClassLoaderTest.java Fri Nov  7 16:40:08 2008
> @@ -19,11 +19,15 @@
>  
>  import java.io.File;
>  import java.net.URL;
> +import java.util.Collections;
> +import java.util.HashSet;
> +import java.util.Set;
>  
>  import org.apache.geronimo.testsupport.TestSupport;
>  
>  import org.apache.geronimo.kernel.config.MultiParentClassLoader;
>  import org.apache.geronimo.kernel.repository.Artifact;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
>  
>  /**
>   * Tests loading various classes (as classes and URL resources) with different
> @@ -33,16 +37,34 @@
>   * @version $Rev$ $Date$
>   */
>  public class ClassLoaderTest extends TestSupport {
> +    private static final Set<String> HIDDEN;
> +    private static final Set<String> NON_OVERRIDABLE;
> +
> +    static {
> +        HIDDEN = new HashSet<String>();
> +        HIDDEN.add("org.apache.geronimo");
> +        HIDDEN.add("org.mortbay");
> +        HIDDEN.add("org.xml");
> +        HIDDEN.add("org.w3c");
> +        
> +        NON_OVERRIDABLE = new HashSet<String>();
> +        NON_OVERRIDABLE.add("java.");
> +        NON_OVERRIDABLE.add("javax.");
> +    }
> +    
>      Artifact configId = new Artifact("foo", "bar", "1", "car");
>      ClassLoader cl;
>      URL[] urls;
> -    private static final String[] HIDDEN = {"org.apache.geronimo", "org.mortbay", "org.xml", "org.w3c"};
> -    private static final String[] NON_OVERRIDABLE = {"java.", "javax."};
> +    private ClassLoadingRules classLoadingRules;
>  
>      public void setUp() throws Exception {
>          super.setUp();
>          URL url = new File(BASEDIR, "src/test/resources/deployables/cltest/").toURL();
>          urls = new URL[]{url};
> +
> +        classLoadingRules = new ClassLoadingRules();
> +        classLoadingRules.getHiddenRule().setClassPrefixes(HIDDEN );
> +        classLoadingRules.getNonOverrideableRule().setClassPrefixes(NON_OVERRIDABLE);
>      }
>  
>      //todo: try more restricted prefixed besides javax.*
> @@ -52,7 +74,7 @@
>       * parent ClassLoader.  This should work.
>       */
>      public void testFalseNonexistantJavaxClass() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), false, HIDDEN, NON_OVERRIDABLE);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          try {
>              cl.loadClass("javax.foo.Foo");
>          } catch(ClassNotFoundException e) {
> @@ -65,7 +87,8 @@
>       * parent ClassLoader.  This should work.
>       */
>      public void testTrueNonexistantJavaxClass() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), true, HIDDEN, NON_OVERRIDABLE);
> +        classLoadingRules.setInverseClassLoading(true);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          try {
>              cl.loadClass("javax.foo.Foo");
>          } catch(ClassNotFoundException e) {
> @@ -79,7 +102,7 @@
>       * This should always load the parent's copy.
>       */
>      public void testFalseExistantJavaxClass() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), false, HIDDEN, NON_OVERRIDABLE);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          try {
>              Class cls = cl.loadClass("javax.servlet.Servlet");
>              assertTrue("Loaded wrong class first; expected to find parent CL's copy of javax.servlet.Servlet",cls.getDeclaredMethods().length > 0);
> @@ -94,7 +117,8 @@
>       * This should always load the parent's copy.
>       */
>      public void testTrueExistantJavaxClass() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), true, HIDDEN, NON_OVERRIDABLE);
> +        classLoadingRules.setInverseClassLoading(true);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          try {
>              Class cls = cl.loadClass("javax.servlet.Servlet");
>              assertTrue("Loaded wrong class first; expected to find parent CL's copy of javax.servlet.Servlet",cls.getDeclaredMethods().length > 0);
> @@ -111,7 +135,7 @@
>       * copy when the contextPriorityClassLoader is set to true.
>       */
>      public void xtestFalseExistantNonJavaxClass() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), false, HIDDEN, NON_OVERRIDABLE);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          try {
>              Class cls = cl.loadClass("mx4j.MBeanDescription");
>              assertTrue("Should not have overriden parent CL definition of class mx4j.MBeanDescription", cls.getDeclaredMethods().length > 0);
> @@ -128,7 +152,8 @@
>       * the contextPriorityClassLoader is set to true (as here).
>       */
>      public void xtestTrueExistantNonJavaxClass() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), true, HIDDEN, NON_OVERRIDABLE);
> +        classLoadingRules.setInverseClassLoading(true);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          try {
>              Class cls = cl.loadClass("mx4j.MBeanDescription");
>              assertTrue("Should be able to override a class that is not in java.*, javax.*, etc.", cls.getDeclaredMethods().length == 0);
> @@ -142,7 +167,7 @@
>       * parent ClassLoader.  This should work.
>       */
>      public void testFalseNonexistantJavaxResource() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), false, HIDDEN, NON_OVERRIDABLE);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          URL url = cl.getResource("javax/foo/Foo.class");
>          if(url == null) {
>              fail("Should be able to load a javax.* class that is not defined by my parent CL");
> @@ -155,7 +180,8 @@
>       * parent ClassLoader.  This should work.
>       */
>      public void testTrueNonexistantJavaxResource() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), true, HIDDEN, NON_OVERRIDABLE);
> +        classLoadingRules.setInverseClassLoading(true);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          URL url = cl.getResource("javax/foo/Foo.class");
>          if(url == null) {
>              fail("Should be able to load a javax.* class that is not defined by my parent CL");
> @@ -169,7 +195,7 @@
>       * This should always load the parent's copy.
>       */
>      public void testFalseExistantJavaxResource() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), false, HIDDEN, NON_OVERRIDABLE);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          URL url = cl.getResource("javax/servlet/Servlet.class");
>          if(url == null) {
>              fail("Problem with test; expecting to have javax.servlet.* on the ClassPath");
> @@ -183,7 +209,8 @@
>       * This should always load the parent's copy.
>       */
>      public void testTrueExistantJavaxResource() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), true, HIDDEN, NON_OVERRIDABLE);
> +        classLoadingRules.setInverseClassLoading(true);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          URL url = cl.getResource("javax/servlet/Servlet.class");
>          if(url == null) {
>              fail("Problem with test; expecting to have javax.servlet.* on the ClassPath");
> @@ -199,7 +226,7 @@
>       * copy when the contextPriorityClassLoader is set to true.
>       */
>      public void xtestFalseExistantNonJavaxResource() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), false, HIDDEN, NON_OVERRIDABLE);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          URL url = cl.getResource("mx4j/MBeanDescription.class");
>          if(url == null) {
>              fail("Problem with test; expecting to have mx4j.* on the ClassPath");
> @@ -215,7 +242,9 @@
>       * the contextPriorityClassLoader is set to true (as here).
>       */
>      public void testTrueExistantNonJavaxResource() {
> -        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), true, new String[] {}, NON_OVERRIDABLE);
> +        classLoadingRules.setInverseClassLoading(true);
> +        classLoadingRules.getHiddenRule().setClassPrefixes(Collections.EMPTY_SET);
> +        cl = new MultiParentClassLoader(configId, urls, getClass().getClassLoader(), classLoadingRules);
>          URL url = cl.getResource("mx4j/MBeanDescription.class");
>          if(url == null) {
>              fail("Problem with test; expecting to have mx4j.* on the ClassPath");
> 
> Modified: geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/XmlUtil.java
> URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/XmlUtil.java?rev=712326&r1=712325&r2=712326&view=diff
> ==============================================================================
> --- geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/XmlUtil.java (original)
> +++ geronimo/server/trunk/plugins/openejb/geronimo-openejb-builder/src/main/java/org/apache/geronimo/openejb/deployment/XmlUtil.java Fri Nov  7 16:40:08 2008
> @@ -17,10 +17,26 @@
>   */
>  package org.apache.geronimo.openejb.deployment;
>  
> +import java.io.ByteArrayOutputStream;
> +import java.io.File;
> +import java.io.FileOutputStream;
> +import java.io.IOException;
> +import java.util.HashSet;
> +import java.util.List;
> +
> +import javax.xml.bind.JAXBContext;
> +import javax.xml.bind.JAXBElement;
> +import javax.xml.bind.JAXBException;
> +import javax.xml.bind.Marshaller;
> +import javax.xml.bind.ValidationEvent;
> +import javax.xml.namespace.QName;
> +
>  import org.apache.geronimo.common.DeploymentException;
>  import org.apache.geronimo.deployment.service.EnvironmentBuilder;
>  import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
>  import org.apache.geronimo.kernel.repository.Artifact;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRule;
> +import org.apache.geronimo.kernel.repository.ClassLoadingRules;
>  import org.apache.geronimo.kernel.repository.Dependency;
>  import org.apache.geronimo.kernel.repository.Environment;
>  import org.apache.geronimo.openejb.xbeans.ejbjar.OpenejbEjbJarDocument;
> @@ -37,24 +53,11 @@
>  import org.apache.openejb.jee.oejb2.EnvironmentType;
>  import org.apache.openejb.jee.oejb2.GeronimoEjbJarType;
>  import org.apache.openejb.jee.oejb2.ImportType;
> -import org.apache.openejb.jee.oejb2.JaxbOpenejbJar2;
>  import org.apache.xmlbeans.XmlCursor;
>  import org.apache.xmlbeans.XmlDocumentProperties;
>  import org.apache.xmlbeans.XmlException;
>  import org.apache.xmlbeans.XmlObject;
>  
> -import javax.xml.bind.JAXBContext;
> -import javax.xml.bind.JAXBElement;
> -import javax.xml.bind.JAXBException;
> -import javax.xml.bind.Marshaller;
> -import javax.xml.bind.ValidationEvent;
> -import javax.xml.namespace.QName;
> -import java.io.ByteArrayOutputStream;
> -import java.io.File;
> -import java.io.FileOutputStream;
> -import java.io.InputStream;
> -import java.io.IOException;
> -
>  public final class XmlUtil {
>      public static final QName OPENEJBJAR_QNAME = OpenejbEjbJarDocument.type.getDocumentElementName();
>      private static final QName CMP_VERSION = new QName(SchemaConversionUtils.J2EE_NAMESPACE, "cmp-version");
> @@ -159,13 +162,22 @@
>                      environment.addDependency(dependency);
>                  }
>              }
> -            environment.setInverseClassLoading(environmentType.isInverseClassloading());
> +            
>              environment.setSuppressDefaultEnvironment(environmentType.isSuppressDefaultEnvironment());
> +
> +            ClassLoadingRules classLoadingRules = environment.getClassLoadingRules();
> +            classLoadingRules.setInverseClassLoading(environmentType.isInverseClassloading());
> +            
>              if (environmentType.getHiddenClasses() != null) {
> -                environment.setHiddenClasses(environmentType.getHiddenClasses().getFilter());
> +                ClassLoadingRule hiddenRule = classLoadingRules.getHiddenRule();
> +                List<String> filter = environmentType.getHiddenClasses().getFilter();
> +                hiddenRule.setClassPrefixes(new HashSet<String>(filter));
>              }
> +            
>              if (environmentType.getNonOverridableClasses() != null) {
> -                environment.setNonOverrideableClasses(environmentType.getNonOverridableClasses().getFilter());
> +                ClassLoadingRule nonOverrideableRule = classLoadingRules.getNonOverrideableRule();
> +                List<String> filter = environmentType.getNonOverridableClasses().getFilter();
> +                nonOverrideableRule.setClassPrefixes(new HashSet<String>(filter));
>              }
>          }
>          if (!environment.isSuppressDefaultEnvironment()) {
> 
> 
> 


Mime
View raw message