You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by gd...@apache.org on 2008/11/08 01:40:09 UTC

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...

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()) {



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...

Posted by Joe Bohn <jo...@earthlink.net>.
Gianny,

Can you provide some more information on how you might accomplish what 
you are proposing?  GeronimoTldLocationsCache is a specialization of the 
Jasper TldLocationsCache functionality and we configure Jasper to use 
our version.  So, much of the fundamental logic involved in resolving 
the tld resources is embedded in Jasper.

See http://svn.apache.org/viewvc?view=rev&rev=517712 for the original 
change and the JIRA https://issues.apache.org/jira/browse/GERONIMO-2955 .

So, if we revert back to the jasper TldLocationsCache our classloader 
implementations of getResource() will never be invoked because we will 
not have traversed the parent classloaders correctly to add them to the 
cache.

Also, given the differences between MultiParentClassLoader and 
ChildrenConfigurationClassLoader it is not clear to me how we would walk 
the appropriate parentage without some type of instance check.  We do 
honor much of the classloading logic there today in walking the 
parentage and eventually when jasper goes about loading the resources.


Joe


Gianny Damour wrote:
> Hi Joe,
> 
> Thanks for your investigations. This is a very good catch.
> 
> Based on a cursory review of GeronimoTldLocationsCache, I believe that 
> the implementation can be improved to remove such a weird instanceof 
> identification mechanism, which is fragile and increases coupling to 
> Geronimo class loading internals. Furthermore, the implementation simply 
> skips any logic, e.g. class loading logic, which is encapsulated within 
> a class loader. An integration analogy would be to directly retrieve 
> stuff from a database instead of going through the application layer 
> providing relevant business logic to retrieve the stuff you are looking 
> for.
> 
> My understanding is that ClassLoader.getResources() can be used to 
> implement GeronimoTldLocationsCache.scanJars without requiring any 
> dependency on MCCL and CCCL.
> 
> Thanks,
> Gianny
> 
> On 21/11/2008, at 6:39 AM, Joe Bohn wrote:
> 
>>
>> I finally just checked in a fix for this.  Turned out it wasn't 
>> related to the resource processing in the classloader ... but rather 
>> to the jasper navigation of the classloader hierarchy that had to be 
>> extended for the new ChildrenConfigurationClassLoader.  See 
>> http://svn.apache.org/viewvc?rev=719329&view=rev
>>
>> Joe
>>
>>
>> Joe Bohn wrote:
>>> I think I'm getting it narrowed down a bit.  It seems that when 
>>> ChildrenConfigurationClassLoader.getResource(name) is called it never 
>>> actually resulting in invoking 
>>> MultiParentClassLoader.getResource(name) (at least not in this case).
>>> The MPCL should have been passed in when the CCCL was constructed. 
>>> CCCL.getResource calls super.getResource (super being 
>>> SecureClassLoader) which should ultimately result in MPCL.getResource 
>>> being invoked - but that doesn't seem to be happening.  Perhaps we 
>>> should update CCCL.getResource to directly invoke MPCL.getResource 
>>> rather than super.getResource?
>>> I guess the other possibility is that the parent isn't what I think 
>>> it should be ... still investigating.
>>> Joe
>>> Joe Bohn wrote:
>>>> Gianny Damour wrote:
>>>>>
>>>>> On 19/11/2008, at 5:19 AM, Joe Bohn wrote:
>>>>>
>>>>>> Joe Bohn wrote:
>>>>>>> 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.
>>>>>>
>>>>>> Correction ... it was not removed but rather changed and 
>>>>>> relocated.  I'm still looking to understand why this is causing a 
>>>>>> problem.
>>>>>
>>>>> Hi,
>>>>>
>>>>> Indeed, I changed the implementation to properly encapsulate class 
>>>>> loading rules. The new implementation is way cleaner this way; when 
>>>>> my frustration coming from reported issues will reduce, I may use 
>>>>> this better encapsulation to add import and export class loading 
>>>>> rules.
>>>>
>>>> I agree that what you added for the ClassLoadingRules is cleaner. 
>>>> However, I think it might be the ChildrenConfigurationClassLoader 
>>>> and it's replacement of MultiParentClassLoader in the Configuration 
>>>> that might be causing us problems.  The testsuite failures that I 
>>>> mentioned are failing as well as nearly all of the jstl tck tests 
>>>> since this change.  Perhaps it is working as designed, but it seems 
>>>> strange to me that as we process the "parent" classloaders they are 
>>>> all of type "ChildrenConfigurationClassLoader" when they used to be 
>>>> "MultiParentClassLoaders".
>>>>
>>>> BTW, I've verified that these tests were not failing prior to this 
>>>> change and begin to fail with just the change a few other necessary 
>>>> changes (the reverting of the xsd changes and fixing the dependency 
>>>> history files).
>>>>
>>>>>
>>>>>>
>>>>>> 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)?
>>>>>
>>>>> If this is indeed a bug related to this change, then let's ensure 
>>>>> that we have a proper unit test to prevent regression. Let's also 
>>>>> ensure that this test is collocated with the proper component to 
>>>>> improve cohesion. I have been observing various changes, many of 
>>>>> them do not have proper unit tests and this causes problems further 
>>>>> down the path as other developers can not safely change code.
>>>>
>>>> I'm fine with that, but I'm sure there are probably a number of more 
>>>> obscure situations that aren't covered by the unit tests ... they 
>>>> can only do so much.  That's one of the reasons for the testsuite.
>>>>
>>>>>
>>>>> Regarding private-classes, the current Geronimo <-> OpenEJB DD 
>>>>> coupling is unfortunate. Does the OpenEJB deployer needs to know 
>>>>> about the Geronimo environment? If it does not need to know about 
>>>>> it, then let's strip from the DD the environment element and pass 
>>>>> to OpenEJB the stripped version. This will reduce a little bit 
>>>>> coupling. Another approach is to transform the Geronimo DD into an 
>>>>> OpenEJB supported DD when it is handed over to OpenEJB (in this 
>>>>> case, we simply remove the private-classes). The creation of a 
>>>>> canonical DD representation between Geronimo and OpenEJB will 
>>>>> reduce coupling.
>>>>>
>>>>> I let you re-revert the private-classes change.
>>>>
>>>> I can't unrevert these changes since I'm not a committer on OpenEJB 
>>>> ... but perhaps we should wait on that anyway until we resolve the 
>>>> JSTL problems.
>>>>
>>>>>
>>>>> Thanks,
>>>>> Gianny
>>>>>
>>>>>
>>>>>>> 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
>>>>
>>>> removed content of original change from this discussion thread.
>>>>
>>
> 
> 


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...

Posted by Gianny Damour <gi...@optusnet.com.au>.
Hi Joe,

Thanks for your investigations. This is a very good catch.

Based on a cursory review of GeronimoTldLocationsCache, I believe  
that the implementation can be improved to remove such a weird  
instanceof identification mechanism, which is fragile and increases  
coupling to Geronimo class loading internals. Furthermore, the  
implementation simply skips any logic, e.g. class loading logic,  
which is encapsulated within a class loader. An integration analogy  
would be to directly retrieve stuff from a database instead of going  
through the application layer providing relevant business logic to  
retrieve the stuff you are looking for.

My understanding is that ClassLoader.getResources() can be used to  
implement GeronimoTldLocationsCache.scanJars without requiring any  
dependency on MCCL and CCCL.

Thanks,
Gianny

On 21/11/2008, at 6:39 AM, Joe Bohn wrote:

>
> I finally just checked in a fix for this.  Turned out it wasn't  
> related to the resource processing in the classloader ... but  
> rather to the jasper navigation of the classloader hierarchy that  
> had to be extended for the new ChildrenConfigurationClassLoader.   
> See http://svn.apache.org/viewvc?rev=719329&view=rev
>
> Joe
>
>
> Joe Bohn wrote:
>> I think I'm getting it narrowed down a bit.  It seems that when  
>> ChildrenConfigurationClassLoader.getResource(name) is called it  
>> never actually resulting in invoking  
>> MultiParentClassLoader.getResource(name) (at least not in this case).
>> The MPCL should have been passed in when the CCCL was constructed.  
>> CCCL.getResource calls super.getResource (super being  
>> SecureClassLoader) which should ultimately result in  
>> MPCL.getResource being invoked - but that doesn't seem to be  
>> happening.  Perhaps we should update CCCL.getResource to directly  
>> invoke MPCL.getResource rather than super.getResource?
>> I guess the other possibility is that the parent isn't what I  
>> think it should be ... still investigating.
>> Joe
>> Joe Bohn wrote:
>>> Gianny Damour wrote:
>>>>
>>>> On 19/11/2008, at 5:19 AM, Joe Bohn wrote:
>>>>
>>>>> Joe Bohn wrote:
>>>>>> 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.
>>>>>
>>>>> Correction ... it was not removed but rather changed and  
>>>>> relocated.  I'm still looking to understand why this is causing  
>>>>> a problem.
>>>>
>>>> Hi,
>>>>
>>>> Indeed, I changed the implementation to properly encapsulate  
>>>> class loading rules. The new implementation is way cleaner this  
>>>> way; when my frustration coming from reported issues will  
>>>> reduce, I may use this better encapsulation to add import and  
>>>> export class loading rules.
>>>
>>> I agree that what you added for the ClassLoadingRules is cleaner.  
>>> However, I think it might be the ChildrenConfigurationClassLoader  
>>> and it's replacement of MultiParentClassLoader in the  
>>> Configuration that might be causing us problems.  The testsuite  
>>> failures that I mentioned are failing as well as nearly all of  
>>> the jstl tck tests since this change.  Perhaps it is working as  
>>> designed, but it seems strange to me that as we process the  
>>> "parent" classloaders they are all of type  
>>> "ChildrenConfigurationClassLoader" when they used to be  
>>> "MultiParentClassLoaders".
>>>
>>> BTW, I've verified that these tests were not failing prior to  
>>> this change and begin to fail with just the change a few other  
>>> necessary changes (the reverting of the xsd changes and fixing  
>>> the dependency history files).
>>>
>>>>
>>>>>
>>>>> 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)?
>>>>
>>>> If this is indeed a bug related to this change, then let's  
>>>> ensure that we have a proper unit test to prevent regression.  
>>>> Let's also ensure that this test is collocated with the proper  
>>>> component to improve cohesion. I have been observing various  
>>>> changes, many of them do not have proper unit tests and this  
>>>> causes problems further down the path as other developers can  
>>>> not safely change code.
>>>
>>> I'm fine with that, but I'm sure there are probably a number of  
>>> more obscure situations that aren't covered by the unit tests ...  
>>> they can only do so much.  That's one of the reasons for the  
>>> testsuite.
>>>
>>>>
>>>> Regarding private-classes, the current Geronimo <-> OpenEJB DD  
>>>> coupling is unfortunate. Does the OpenEJB deployer needs to know  
>>>> about the Geronimo environment? If it does not need to know  
>>>> about it, then let's strip from the DD the environment element  
>>>> and pass to OpenEJB the stripped version. This will reduce a  
>>>> little bit coupling. Another approach is to transform the  
>>>> Geronimo DD into an OpenEJB supported DD when it is handed over  
>>>> to OpenEJB (in this case, we simply remove the private-classes).  
>>>> The creation of a canonical DD representation between Geronimo  
>>>> and OpenEJB will reduce coupling.
>>>>
>>>> I let you re-revert the private-classes change.
>>>
>>> I can't unrevert these changes since I'm not a committer on  
>>> OpenEJB ... but perhaps we should wait on that anyway until we  
>>> resolve the JSTL problems.
>>>
>>>>
>>>> Thanks,
>>>> Gianny
>>>>
>>>>
>>>>>> 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
>>>
>>> removed content of original change from this discussion thread.
>>>
>


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...

Posted by Joe Bohn <jo...@earthlink.net>.
I finally just checked in a fix for this.  Turned out it wasn't related 
to the resource processing in the classloader ... but rather to the 
jasper navigation of the classloader hierarchy that had to be extended 
for the new ChildrenConfigurationClassLoader.  See 
http://svn.apache.org/viewvc?rev=719329&view=rev

Joe


Joe Bohn wrote:
> I think I'm getting it narrowed down a bit.  It seems that when 
> ChildrenConfigurationClassLoader.getResource(name) is called it never 
> actually resulting in invoking MultiParentClassLoader.getResource(name) 
> (at least not in this case).
> 
> The MPCL should have been passed in when the CCCL was constructed. 
> CCCL.getResource calls super.getResource (super being SecureClassLoader) 
> which should ultimately result in MPCL.getResource being invoked - but 
> that doesn't seem to be happening.  Perhaps we should update 
> CCCL.getResource to directly invoke MPCL.getResource rather than 
> super.getResource?
> 
> I guess the other possibility is that the parent isn't what I think it 
> should be ... still investigating.
> 
> 
> Joe
> 
> 
> Joe Bohn wrote:
>> Gianny Damour wrote:
>>>
>>> On 19/11/2008, at 5:19 AM, Joe Bohn wrote:
>>>
>>>> Joe Bohn wrote:
>>>>> 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.
>>>>
>>>> Correction ... it was not removed but rather changed and relocated.  
>>>> I'm still looking to understand why this is causing a problem.
>>>
>>> Hi,
>>>
>>> Indeed, I changed the implementation to properly encapsulate class 
>>> loading rules. The new implementation is way cleaner this way; when 
>>> my frustration coming from reported issues will reduce, I may use 
>>> this better encapsulation to add import and export class loading rules.
>>
>> I agree that what you added for the ClassLoadingRules is cleaner. 
>> However, I think it might be the ChildrenConfigurationClassLoader and 
>> it's replacement of MultiParentClassLoader in the Configuration that 
>> might be causing us problems.  The testsuite failures that I mentioned 
>> are failing as well as nearly all of the jstl tck tests since this 
>> change.  Perhaps it is working as designed, but it seems strange to me 
>> that as we process the "parent" classloaders they are all of type 
>> "ChildrenConfigurationClassLoader" when they used to be 
>> "MultiParentClassLoaders".
>>
>> BTW, I've verified that these tests were not failing prior to this 
>> change and begin to fail with just the change a few other necessary 
>> changes (the reverting of the xsd changes and fixing the dependency 
>> history files).
>>
>>>
>>>>
>>>> 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)?
>>>
>>> If this is indeed a bug related to this change, then let's ensure 
>>> that we have a proper unit test to prevent regression. Let's also 
>>> ensure that this test is collocated with the proper component to 
>>> improve cohesion. I have been observing various changes, many of them 
>>> do not have proper unit tests and this causes problems further down 
>>> the path as other developers can not safely change code.
>>
>> I'm fine with that, but I'm sure there are probably a number of more 
>> obscure situations that aren't covered by the unit tests ... they can 
>> only do so much.  That's one of the reasons for the testsuite.
>>
>>>
>>> Regarding private-classes, the current Geronimo <-> OpenEJB DD 
>>> coupling is unfortunate. Does the OpenEJB deployer needs to know 
>>> about the Geronimo environment? If it does not need to know about it, 
>>> then let's strip from the DD the environment element and pass to 
>>> OpenEJB the stripped version. This will reduce a little bit coupling. 
>>> Another approach is to transform the Geronimo DD into an OpenEJB 
>>> supported DD when it is handed over to OpenEJB (in this case, we 
>>> simply remove the private-classes). The creation of a canonical DD 
>>> representation between Geronimo and OpenEJB will reduce coupling.
>>>
>>> I let you re-revert the private-classes change.
>>
>> I can't unrevert these changes since I'm not a committer on OpenEJB 
>> ... but perhaps we should wait on that anyway until we resolve the 
>> JSTL problems.
>>
>>>
>>> Thanks,
>>> Gianny
>>>
>>>
>>>>> 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
>>
>> removed content of original change from this discussion thread.
>>
> 
> 


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...

Posted by Joe Bohn <jo...@earthlink.net>.
I think I'm getting it narrowed down a bit.  It seems that when 
ChildrenConfigurationClassLoader.getResource(name) is called it never 
actually resulting in invoking MultiParentClassLoader.getResource(name) 
(at least not in this case).

The MPCL should have been passed in when the CCCL was constructed. 
CCCL.getResource calls super.getResource (super being SecureClassLoader) 
which should ultimately result in MPCL.getResource being invoked - but 
that doesn't seem to be happening.  Perhaps we should update 
CCCL.getResource to directly invoke MPCL.getResource rather than 
super.getResource?

I guess the other possibility is that the parent isn't what I think it 
should be ... still investigating.


Joe


Joe Bohn wrote:
> Gianny Damour wrote:
>>
>> On 19/11/2008, at 5:19 AM, Joe Bohn wrote:
>>
>>> Joe Bohn wrote:
>>>> 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.
>>>
>>> Correction ... it was not removed but rather changed and relocated.  
>>> I'm still looking to understand why this is causing a problem.
>>
>> Hi,
>>
>> Indeed, I changed the implementation to properly encapsulate class 
>> loading rules. The new implementation is way cleaner this way; when my 
>> frustration coming from reported issues will reduce, I may use this 
>> better encapsulation to add import and export class loading rules.
> 
> I agree that what you added for the ClassLoadingRules is cleaner. 
> However, I think it might be the ChildrenConfigurationClassLoader and 
> it's replacement of MultiParentClassLoader in the Configuration that 
> might be causing us problems.  The testsuite failures that I mentioned 
> are failing as well as nearly all of the jstl tck tests since this 
> change.  Perhaps it is working as designed, but it seems strange to me 
> that as we process the "parent" classloaders they are all of type 
> "ChildrenConfigurationClassLoader" when they used to be 
> "MultiParentClassLoaders".
> 
> BTW, I've verified that these tests were not failing prior to this 
> change and begin to fail with just the change a few other necessary 
> changes (the reverting of the xsd changes and fixing the dependency 
> history files).
> 
>>
>>>
>>> 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)?
>>
>> If this is indeed a bug related to this change, then let's ensure that 
>> we have a proper unit test to prevent regression. Let's also ensure 
>> that this test is collocated with the proper component to improve 
>> cohesion. I have been observing various changes, many of them do not 
>> have proper unit tests and this causes problems further down the path 
>> as other developers can not safely change code.
> 
> I'm fine with that, but I'm sure there are probably a number of more 
> obscure situations that aren't covered by the unit tests ... they can 
> only do so much.  That's one of the reasons for the testsuite.
> 
>>
>> Regarding private-classes, the current Geronimo <-> OpenEJB DD 
>> coupling is unfortunate. Does the OpenEJB deployer needs to know about 
>> the Geronimo environment? If it does not need to know about it, then 
>> let's strip from the DD the environment element and pass to OpenEJB 
>> the stripped version. This will reduce a little bit coupling. Another 
>> approach is to transform the Geronimo DD into an OpenEJB supported DD 
>> when it is handed over to OpenEJB (in this case, we simply remove the 
>> private-classes). The creation of a canonical DD representation 
>> between Geronimo and OpenEJB will reduce coupling.
>>
>> I let you re-revert the private-classes change.
> 
> I can't unrevert these changes since I'm not a committer on OpenEJB ... 
> but perhaps we should wait on that anyway until we resolve the JSTL 
> problems.
> 
>>
>> Thanks,
>> Gianny
>>
>>
>>>> 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
> 
> removed content of original change from this discussion thread.
> 


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...

Posted by Joe Bohn <jo...@earthlink.net>.
Gianny Damour wrote:
> 
> On 19/11/2008, at 5:19 AM, Joe Bohn wrote:
> 
>> Joe Bohn wrote:
>>> 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.
>>
>> Correction ... it was not removed but rather changed and relocated.  
>> I'm still looking to understand why this is causing a problem.
> 
> Hi,
> 
> Indeed, I changed the implementation to properly encapsulate class 
> loading rules. The new implementation is way cleaner this way; when my 
> frustration coming from reported issues will reduce, I may use this 
> better encapsulation to add import and export class loading rules.

I agree that what you added for the ClassLoadingRules is cleaner. 
However, I think it might be the ChildrenConfigurationClassLoader and 
it's replacement of MultiParentClassLoader in the Configuration that 
might be causing us problems.  The testsuite failures that I mentioned 
are failing as well as nearly all of the jstl tck tests since this 
change.  Perhaps it is working as designed, but it seems strange to me 
that as we process the "parent" classloaders they are all of type 
"ChildrenConfigurationClassLoader" when they used to be 
"MultiParentClassLoaders".

BTW, I've verified that these tests were not failing prior to this 
change and begin to fail with just the change a few other necessary 
changes (the reverting of the xsd changes and fixing the dependency 
history files).

> 
>>
>> 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)?
> 
> If this is indeed a bug related to this change, then let's ensure that 
> we have a proper unit test to prevent regression. Let's also ensure that 
> this test is collocated with the proper component to improve cohesion. I 
> have been observing various changes, many of them do not have proper 
> unit tests and this causes problems further down the path as other 
> developers can not safely change code.

I'm fine with that, but I'm sure there are probably a number of more 
obscure situations that aren't covered by the unit tests ... they can 
only do so much.  That's one of the reasons for the testsuite.

> 
> Regarding private-classes, the current Geronimo <-> OpenEJB DD coupling 
> is unfortunate. Does the OpenEJB deployer needs to know about the 
> Geronimo environment? If it does not need to know about it, then let's 
> strip from the DD the environment element and pass to OpenEJB the 
> stripped version. This will reduce a little bit coupling. Another 
> approach is to transform the Geronimo DD into an OpenEJB supported DD 
> when it is handed over to OpenEJB (in this case, we simply remove the 
> private-classes). The creation of a canonical DD representation between 
> Geronimo and OpenEJB will reduce coupling.
> 
> I let you re-revert the private-classes change.

I can't unrevert these changes since I'm not a committer on OpenEJB ... 
but perhaps we should wait on that anyway until we resolve the JSTL 
problems.

> 
> Thanks,
> Gianny
> 
> 
>>> 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

removed content of original change from this discussion thread.

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...

Posted by David Jencks <da...@yahoo.com>.

On Nov 18, 2008, at 12:39 PM, Gianny Damour wrote:
>
> On 19/11/2008, at 5:19 AM, Joe Bohn wrote:
>
>> Joe Bohn wrote:
>>> 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.
>>
>> Correction ... it was not removed but rather changed and  
>> relocated.  I'm still looking to understand why this is causing a  
>> problem.
>
> Hi,
>
> Indeed, I changed the implementation to properly encapsulate class  
> loading rules. The new implementation is way cleaner this way; when  
> my frustration coming from reported issues will reduce, I may use  
> this better encapsulation to add import and export class loading  
> rules.
>
>>
>> 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)?
>
> If this is indeed a bug related to this change, then let's ensure  
> that we have a proper unit test to prevent regression. Let's also  
> ensure that this test is collocated with the proper component to  
> improve cohesion. I have been observing various changes, many of  
> them do not have proper unit tests and this causes problems further  
> down the path as other developers can not safely change code.
>
> Regarding private-classes, the current Geronimo <-> OpenEJB DD  
> coupling is unfortunate. Does the OpenEJB deployer needs to know  
> about the Geronimo environment? If it does not need to know about  
> it, then let's strip from the DD the environment element and pass to  
> OpenEJB the stripped version. This will reduce a little bit  
> coupling. Another approach is to transform the Geronimo DD into an  
> OpenEJB supported DD when it is handed over to OpenEJB (in this  
> case, we simply remove the private-classes). The creation of a  
> canonical DD representation between Geronimo and OpenEJB will reduce  
> coupling.

I think the problem is caused by mismatch between our xmlbeans plan  
handling and the openejb jaxb plan handling.  Maybe we should consider  
moving the jaxb classes to a more neutral location?  This will  
probably take some work though.

thanks
david jencks
>
>
> I let you re-revert the private-classes change.
>
> Thanks,
> Gianny
>

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...

Posted by Gianny Damour <gi...@optusnet.com.au>.
On 19/11/2008, at 5:19 AM, Joe Bohn wrote:

> Joe Bohn wrote:
>> 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.
>
> Correction ... it was not removed but rather changed and  
> relocated.  I'm still looking to understand why this is causing a  
> problem.

Hi,

Indeed, I changed the implementation to properly encapsulate class  
loading rules. The new implementation is way cleaner this way; when  
my frustration coming from reported issues will reduce, I may use  
this better encapsulation to add import and export class loading rules.

>
> 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)?

If this is indeed a bug related to this change, then let's ensure  
that we have a proper unit test to prevent regression. Let's also  
ensure that this test is collocated with the proper component to  
improve cohesion. I have been observing various changes, many of them  
do not have proper unit tests and this causes problems further down  
the path as other developers can not safely change code.

Regarding private-classes, the current Geronimo <-> OpenEJB DD  
coupling is unfortunate. Does the OpenEJB deployer needs to know  
about the Geronimo environment? If it does not need to know about it,  
then let's strip from the DD the environment element and pass to  
OpenEJB the stripped version. This will reduce a little bit coupling.  
Another approach is to transform the Geronimo DD into an OpenEJB  
supported DD when it is handed over to OpenEJB (in this case, we  
simply remove the private-classes). The creation of a canonical DD  
representation between Geronimo and OpenEJB will reduce coupling.

I let you re-revert the private-classes change.

Thanks,
Gianny


>> 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()) {
>>>
>>>
>>>
>


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...

Posted by Joe Bohn <jo...@earthlink.net>.
Joe Bohn wrote:
> 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.  

Correction ... it was not removed but rather changed and relocated.  I'm 
still looking to understand why this is causing a problem.

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()) {
>>
>>
>>
> 
> 


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...

Posted by Joe Bohn <jo...@earthlink.net>.
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()) {
> 
> 
>