You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by rs...@apache.org on 2002/12/12 23:35:40 UTC

cvs commit: jakarta-commons/discovery/src/test testResource

rsitze      2002/12/12 14:35:40

  Modified:    discovery/src/test/org/apache/commons/discovery/test
                        TestAll.java
               discovery build.xml
               discovery/sandbox/java/org/apache/commons/discovery/jdk
                        JDK11Hooks.java JDK12Hooks.java
               discovery/src/java/org/apache/commons/discovery/jdk
                        JDK12Hooks.java JDK11Hooks.java
  Added:       discovery/src/testAlt2 testResource
               discovery/src/testAlt1 testResource
               discovery/src/test testResource
  Log:
  ClassLoader.getResources() is declared final in all current JDK specs.
  ClassLoaders that change expected behavior by searching parents
  last, instead of first, (as with some J2EE environments/settings) will then
  return a different result for the FIRST value of getResources() versus
  a call to getResource().  This can cause unexpected (and difficult to
  debug) behavior if the discovery mechanism is used to find ONE resource.
  Discovery abstracts the classloader behavior, so we use that abstraction
  to force the first value returned by 'getResources' to be the value
  returned by 'getResource'.
  
  Revision  Changes    Path
  1.6       +56 -4     jakarta-commons/discovery/src/test/org/apache/commons/discovery/test/TestAll.java
  
  Index: TestAll.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/test/org/apache/commons/discovery/test/TestAll.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- TestAll.java	12 Oct 2002 17:26:08 -0000	1.5
  +++ TestAll.java	12 Dec 2002 22:35:39 -0000	1.6
  @@ -63,22 +63,27 @@
   package org.apache.commons.discovery.test;
   
   
  +import java.net.URL;
   import java.util.Properties;
   
   import junit.framework.Test;
   import junit.framework.TestCase;
   import junit.framework.TestSuite;
   
  +import org.apache.commons.discovery.Resource;
   import org.apache.commons.discovery.ResourceClass;
   import org.apache.commons.discovery.ResourceClassIterator;
  +import org.apache.commons.discovery.ResourceIterator;
  +import org.apache.commons.discovery.jdk.JDKHooks;
  +import org.apache.commons.discovery.resource.ClassLoaders;
  +import org.apache.commons.discovery.resource.DiscoverResources;
  +import org.apache.commons.discovery.resource.classes.DiscoverClasses;
   import org.apache.commons.discovery.tools.DefaultClassHolder;
   import org.apache.commons.discovery.tools.DiscoverClass;
   import org.apache.commons.discovery.tools.DiscoverSingleton;
   import org.apache.commons.discovery.tools.ManagedProperties;
   import org.apache.commons.discovery.tools.PropertiesHolder;
   import org.apache.commons.discovery.tools.SPInterface;
  -import org.apache.commons.discovery.resource.ClassLoaders;
  -import org.apache.commons.discovery.resource.classes.DiscoverClasses;
   
   
   /**
  @@ -88,6 +93,7 @@
   public class TestAll extends TestCase {
       private static final int logLevel =
           org.apache.commons.discovery.log.SimpleLog.LOG_LEVEL_INFO;
  +//        org.apache.commons.discovery.log.SimpleLog.LOG_LEVEL_DEBUG;
   
       
       public TestAll(String testName) {
  @@ -243,7 +249,6 @@
       }
   
       public void testFindServiceFileDefault() {
  -//        org.apache.commons.discovery.log.SimpleLog.setLevel(org.apache.commons.discovery.log.SimpleLog.LOG_LEVEL_DEBUG);
           org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
   
           TestInterface2 ti = null;
  @@ -262,6 +267,8 @@
       }
   
       public void testLowLevelFind() {
  +        org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
  +
           ClassLoaders loaders = ClassLoaders.getAppLoaders(TestInterface2.class, getClass(), false);
           String name = "org.apache.commons.discovery.test.TestImpl2_1";
           
  @@ -280,11 +287,56 @@
                   fail("Could not load service: " + resource );
               }
           }
  -        fail("failed to load resource: " + name);
  +        fail("failed to load class resource: " + name);
  +    }
  +    
  +    public void testFindResources() {
  +        org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
  +
  +        ClassLoaders loaders = new ClassLoaders();
  +
  +        /**
  +         * To many class loaders when searching for multiple
  +         * resources means that we can find the same (same URL)
  +         * resource for each loader...
  +         * let's keep this to a minimum.
  +         */
  +        ClassLoader cl = getClass().getClassLoader();
  +        if (cl != null)
  +            loaders.put(getClass().getClassLoader(), true);
  +        else
  +            loaders.put(JDKHooks.getJDKHooks().getSystemClassLoader(), true);
  +        
  +
  +        String name = "testResource";
  +        
  +        String partialPaths[] = { "/test/", "/testAlt1/", "/testAlt2/" };
  +        int expected = partialPaths.length;
  +        
  +        DiscoverResources discovery = new DiscoverResources(loaders);
  +        ResourceIterator iter = discovery.findResources(name);
  +        int count = 0;
  +        while (iter.hasNext()) {
  +            Resource resource = iter.nextResource();
  +            URL url = resource.getResource();
  +            if ( url != null ) {
  +                System.out.println("URL = " + url.toString());
  +                
  +                if (url.getFile().indexOf(partialPaths[count]) == -1) {
  +                    fail("expected to locate URL containing " + partialPaths[count]);
  +                }
  +                count++;
  +            }
  +        }
           
  +        if (count != expected) {
  +            fail("located " + count + " resources, failed to locate all " + expected + " resources: " + name);
  +        }
       }
   
       public void testViaDiscoverClass() {
  +        org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
  +
           ClassLoaders loaders = ClassLoaders.getAppLoaders(TestInterface2.class, getClass(), false);
           
           DiscoverClass discover = new DiscoverClass(loaders);
  
  
  
  1.9       +15 -4     jakarta-commons/discovery/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/build.xml,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- build.xml	12 Sep 2002 16:31:14 -0000	1.8
  +++ build.xml	12 Dec 2002 22:35:39 -0000	1.9
  @@ -74,7 +74,12 @@
     <!-- Construct unit test classpath -->
     <path id="test.classpath">
       <pathelement location="${build.home}/classes"/>
  -    <pathelement location="${build.home}/tests"/>
  +
  +    <!-- test depends on the order of the following 3 lines: -->
  +    <pathelement location="${build.home}/test"/>
  +    <pathelement location="${build.home}/testAlt1"/>
  +    <pathelement location="${build.home}/testAlt2"/>
  +
       <pathelement location="${logger.jar}"/>
       <pathelement location="${junit.jar}"/>
     </path>
  @@ -102,7 +107,7 @@
       <mkdir dir="${build.home}/conf"/>
       <mkdir dir="${build.home}/docs"/>
       <mkdir dir="${build.home}/docs/api"/>
  -    <mkdir dir="${build.home}/tests"/>
  +    <mkdir dir="${build.home}/test"/>
       <tstamp/>
       <copy todir="${build.home}/conf" filtering="on">
         <fileset dir="${conf.home}" includes="*.MF"/>
  @@ -172,14 +177,20 @@
   
     <target name="compile.tests" depends="compile" description="Compile unit test cases">
       <javac  srcdir="${test.home}"
  -           destdir="${build.home}/tests"
  +           destdir="${build.home}/test"
                debug="${compile.debug}"
          deprecation="${compile.deprecation}"
             optimize="${compile.optimize}">
         <classpath refid="test.classpath"/>
       </javac>
  -    <copy    todir="${build.home}/tests" filtering="on">
  +    <copy    todir="${build.home}/test" filtering="on">
         <fileset dir="${test.home}" excludes="**/*.java"/>
  +    </copy>
  +    <copy    todir="${build.home}/testAlt1" filtering="on">
  +      <fileset dir="${test.home}/../testAlt1" excludes="**/*.java"/>
  +    </copy>
  +    <copy    todir="${build.home}/testAlt2" filtering="on">
  +      <fileset dir="${test.home}/../testAlt2" excludes="**/*.java"/>
       </copy>
     </target>
   
  
  
  
  1.2       +73 -2     jakarta-commons/discovery/sandbox/java/org/apache/commons/discovery/jdk/JDK11Hooks.java
  
  Index: JDK11Hooks.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/sandbox/java/org/apache/commons/discovery/jdk/JDK11Hooks.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JDK11Hooks.java	1 Sep 2002 04:12:48 -0000	1.1
  +++ JDK11Hooks.java	12 Dec 2002 22:35:39 -0000	1.2
  @@ -107,8 +107,79 @@
           throws IOException
       {
           /**
  -         * Not yet implemented...
  +         * The simple answer is/was:
  +         *    return loader.getResources(resourceName);
  +         * 
  +         * However, some classloaders overload the behavior of getResource
  +         * (loadClass, etc) such that the order of returned results changes
  +         * from normally expected behavior.
  +         * 
  +         * Example: locate classes/resources from child ClassLoaders first,
  +         *          parents last (in some J2EE environs).
  +         * 
  +         * The resource returned by getResource() should be the same as the
  +         * first resource returned by getResources().  Unfortunately, this
  +         * is not, and cannot be: getResources() is 'final' in the current
  +         * JDK's (1.2, 1.3, 1.4).
  +         * 
  +         * To address this, the implementation of this method will
  +         * return an Enumeration such that the first element is the
  +         * results of getResource, and all trailing elements are
  +         * from getResources.  On each iteration, we check so see
  +         * if the resource (from getResources) matches the first resource,
  +         * and eliminate the redundent element.
            */
  -        return null;
  +        
  +        final URL first = (URL)loader.getResource(resourceName);
  +        final Enumeration rest = loader.getResources(resourceName);
  +        
  +        return new Enumeration() {
  +            private boolean firstDone = (first == null);
  +            private URL next = getNext();
  +            
  +            public Object nextElement() {
  +                URL o = next;
  +                next = getNext();
  +                return o;
  +            }
  +
  +            public boolean hasMoreElements() {
  +                return next != null;
  +            }
  +            
  +            private URL getNext() {
  +                URL n;
  +                
  +                if (!firstDone) {
  +                    /**
  +                     * First time through, use results of getReference()
  +                     * if they were non-null.
  +                     */
  +                    firstDone = true;
  +                    n = first;
  +                } else {
  +                    /**
  +                     * Subsequent times through,
  +                     * use results of getReferences()
  +                     * but take out anything that matches 'first'.
  +                     * 
  +                     * Iterate through list until we find one that
  +                     * doesn't match 'first'.
  +                     */
  +                    n = null;
  +                    while (rest.hasMoreElements()  &&  n == null) {
  +                        n = (URL)rest.nextElement();
  +                        if (first != null &&
  +                            n != null &&
  +                            n.equals(first))
  +                        {
  +                            n = null;
  +                        }
  +                    }
  +                }
  +                
  +                return n;
  +            }
  +        };
       }
   }
  
  
  
  1.2       +76 -2     jakarta-commons/discovery/sandbox/java/org/apache/commons/discovery/jdk/JDK12Hooks.java
  
  Index: JDK12Hooks.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/sandbox/java/org/apache/commons/discovery/jdk/JDK12Hooks.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JDK12Hooks.java	1 Sep 2002 04:12:48 -0000	1.1
  +++ JDK12Hooks.java	12 Dec 2002 22:35:39 -0000	1.2
  @@ -124,12 +124,86 @@
       }
   
       /**
  -     * Implement ClassLoader.getResources for JDK 1.1
  +     * Implement ClassLoader.getResources for JDK 1.2
        */
       public Enumeration getResources(ClassLoader loader,
                                       String resourceName)
           throws IOException
       {
  -        return loader.getResources(resourceName);
  +        /**
  +         * The simple answer is/was:
  +         *    return loader.getResources(resourceName);
  +         * 
  +         * However, some classloaders overload the behavior of getResource
  +         * (loadClass, etc) such that the order of returned results changes
  +         * from normally expected behavior.
  +         * 
  +         * Example: locate classes/resources from child ClassLoaders first,
  +         *          parents last (in some J2EE environs).
  +         * 
  +         * The resource returned by getResource() should be the same as the
  +         * first resource returned by getResources().  Unfortunately, this
  +         * is not, and cannot be: getResources() is 'final' in the current
  +         * JDK's (1.2, 1.3, 1.4).
  +         * 
  +         * To address this, the implementation of this method will
  +         * return an Enumeration such that the first element is the
  +         * results of getResource, and all trailing elements are
  +         * from getResources.  On each iteration, we check so see
  +         * if the resource (from getResources) matches the first resource,
  +         * and eliminate the redundent element.
  +         */
  +        
  +        final URL first = (URL)loader.getResource(resourceName);
  +        final Enumeration rest = loader.getResources(resourceName);
  +        
  +        return new Enumeration() {
  +            private boolean firstDone = (first == null);
  +            private URL next = getNext();
  +            
  +            public Object nextElement() {
  +                URL o = next;
  +                next = getNext();
  +                return o;
  +            }
  +
  +            public boolean hasMoreElements() {
  +                return next != null;
  +            }
  +            
  +            private URL getNext() {
  +                URL n;
  +                
  +                if (!firstDone) {
  +                    /**
  +                     * First time through, use results of getReference()
  +                     * if they were non-null.
  +                     */
  +                    firstDone = true;
  +                    n = first;
  +                } else {
  +                    /**
  +                     * Subsequent times through,
  +                     * use results of getReferences()
  +                     * but take out anything that matches 'first'.
  +                     * 
  +                     * Iterate through list until we find one that
  +                     * doesn't match 'first'.
  +                     */
  +                    n = null;
  +                    while (rest.hasMoreElements()  &&  n == null) {
  +                        n = (URL)rest.nextElement();
  +                        if (first != null &&
  +                            n != null &&
  +                            n.equals(first))
  +                        {
  +                            n = null;
  +                        }
  +                    }
  +                }
  +                
  +                return n;
  +            }
  +        };
       }
   }
  
  
  
  1.2       +78 -3     jakarta-commons/discovery/src/java/org/apache/commons/discovery/jdk/JDK12Hooks.java
  
  Index: JDK12Hooks.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/jdk/JDK12Hooks.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JDK12Hooks.java	23 Aug 2002 00:15:25 -0000	1.1
  +++ JDK12Hooks.java	12 Dec 2002 22:35:39 -0000	1.2
  @@ -61,8 +61,9 @@
   
   package org.apache.commons.discovery.jdk;
   
  -import java.util.Enumeration;
   import java.io.IOException;
  +import java.net.URL;
  +import java.util.Enumeration;
   
   
   /**
  @@ -124,12 +125,86 @@
       }
   
       /**
  -     * Implement ClassLoader.getResources for JDK 1.1
  +     * Implement ClassLoader.getResources for JDK 1.2
        */
       public Enumeration getResources(ClassLoader loader,
                                       String resourceName)
           throws IOException
       {
  -        return loader.getResources(resourceName);
  +        /**
  +         * The simple answer is/was:
  +         *    return loader.getResources(resourceName);
  +         * 
  +         * However, some classloaders overload the behavior of getResource
  +         * (loadClass, etc) such that the order of returned results changes
  +         * from normally expected behavior.
  +         * 
  +         * Example: locate classes/resources from child ClassLoaders first,
  +         *          parents last (in some J2EE environs).
  +         * 
  +         * The resource returned by getResource() should be the same as the
  +         * first resource returned by getResources().  Unfortunately, this
  +         * is not, and cannot be: getResources() is 'final' in the current
  +         * JDK's (1.2, 1.3, 1.4).
  +         * 
  +         * To address this, the implementation of this method will
  +         * return an Enumeration such that the first element is the
  +         * results of getResource, and all trailing elements are
  +         * from getResources.  On each iteration, we check so see
  +         * if the resource (from getResources) matches the first resource,
  +         * and eliminate the redundent element.
  +         */
  +        
  +        final URL first = (URL)loader.getResource(resourceName);
  +        final Enumeration rest = loader.getResources(resourceName);
  +        
  +        return new Enumeration() {
  +            private boolean firstDone = (first == null);
  +            private URL next = getNext();
  +            
  +            public Object nextElement() {
  +                URL o = next;
  +                next = getNext();
  +                return o;
  +            }
  +
  +            public boolean hasMoreElements() {
  +                return next != null;
  +            }
  +            
  +            private URL getNext() {
  +                URL n;
  +                
  +                if (!firstDone) {
  +                    /**
  +                     * First time through, use results of getReference()
  +                     * if they were non-null.
  +                     */
  +                    firstDone = true;
  +                    n = first;
  +                } else {
  +                    /**
  +                     * Subsequent times through,
  +                     * use results of getReferences()
  +                     * but take out anything that matches 'first'.
  +                     * 
  +                     * Iterate through list until we find one that
  +                     * doesn't match 'first'.
  +                     */
  +                    n = null;
  +                    while (rest.hasMoreElements()  &&  n == null) {
  +                        n = (URL)rest.nextElement();
  +                        if (first != null &&
  +                            n != null &&
  +                            n.equals(first))
  +                        {
  +                            n = null;
  +                        }
  +                    }
  +                }
  +                
  +                return n;
  +            }
  +        };
       }
   }
  
  
  
  1.2       +75 -3     jakarta-commons/discovery/src/java/org/apache/commons/discovery/jdk/JDK11Hooks.java
  
  Index: JDK11Hooks.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/jdk/JDK11Hooks.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JDK11Hooks.java	23 Aug 2002 00:15:25 -0000	1.1
  +++ JDK11Hooks.java	12 Dec 2002 22:35:39 -0000	1.2
  @@ -61,8 +61,9 @@
   
   package org.apache.commons.discovery.jdk;
   
  -import java.util.Enumeration;
   import java.io.IOException;
  +import java.net.URL;
  +import java.util.Enumeration;
   
   
   /**
  @@ -107,8 +108,79 @@
           throws IOException
       {
           /**
  -         * Not yet implemented...
  +         * The simple answer is/was:
  +         *    return loader.getResources(resourceName);
  +         * 
  +         * However, some classloaders overload the behavior of getResource
  +         * (loadClass, etc) such that the order of returned results changes
  +         * from normally expected behavior.
  +         * 
  +         * Example: locate classes/resources from child ClassLoaders first,
  +         *          parents last (in some J2EE environs).
  +         * 
  +         * The resource returned by getResource() should be the same as the
  +         * first resource returned by getResources().  Unfortunately, this
  +         * is not, and cannot be: getResources() is 'final' in the current
  +         * JDK's (1.2, 1.3, 1.4).
  +         * 
  +         * To address this, the implementation of this method will
  +         * return an Enumeration such that the first element is the
  +         * results of getResource, and all trailing elements are
  +         * from getResources.  On each iteration, we check so see
  +         * if the resource (from getResources) matches the first resource,
  +         * and eliminate the redundent element.
            */
  -        return null;
  +        
  +        final URL first = (URL)loader.getResource(resourceName);
  +        final Enumeration rest = loader.getResources(resourceName);
  +        
  +        return new Enumeration() {
  +            private boolean firstDone = (first == null);
  +            private URL next = getNext();
  +            
  +            public Object nextElement() {
  +                URL o = next;
  +                next = getNext();
  +                return o;
  +            }
  +
  +            public boolean hasMoreElements() {
  +                return next != null;
  +            }
  +            
  +            private URL getNext() {
  +                URL n;
  +                
  +                if (!firstDone) {
  +                    /**
  +                     * First time through, use results of getReference()
  +                     * if they were non-null.
  +                     */
  +                    firstDone = true;
  +                    n = first;
  +                } else {
  +                    /**
  +                     * Subsequent times through,
  +                     * use results of getReferences()
  +                     * but take out anything that matches 'first'.
  +                     * 
  +                     * Iterate through list until we find one that
  +                     * doesn't match 'first'.
  +                     */
  +                    n = null;
  +                    while (rest.hasMoreElements()  &&  n == null) {
  +                        n = (URL)rest.nextElement();
  +                        if (first != null &&
  +                            n != null &&
  +                            n.equals(first))
  +                        {
  +                            n = null;
  +                        }
  +                    }
  +                }
  +                
  +                return n;
  +            }
  +        };
       }
   }
  
  
  
  1.1                  jakarta-commons/discovery/src/testAlt2/testResource
  
  Index: testResource
  ===================================================================
  this is a resource for the test(s) to find..
  
  
  1.1                  jakarta-commons/discovery/src/testAlt1/testResource
  
  Index: testResource
  ===================================================================
  this is a resource for the test(s) to find..
  
  
  1.1                  jakarta-commons/discovery/src/test/testResource
  
  Index: testResource
  ===================================================================
  this is a resource for the test(s) to find..
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>