Author: skitching
Date: Tue Aug  1 16:48:14 2006
New Revision: 427800

URL: http://svn.apache.org/viewvc?rev=427800&view=rev
Log:
Manually force our custom java.util.logging.Handler class to be loaded via the
system classloader. This means that the unit test can successfully run even
when the class is not in the system classpath (as happens when running tests
with maven2's surefire plugin for example).

Modified:
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java
    
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigTestCase.java

Modified: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java?rev=427800&r1=427799&r2=427800&view=diff
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java
 (original)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigAPITestCase.java
 Tue Aug  1 16:48:14 2006
@@ -19,8 +19,8 @@
 
 import junit.framework.Test;
 
-import org.apache.commons.logging.PathableTestSuite;
 import org.apache.commons.logging.PathableClassLoader;
+import org.apache.commons.logging.PathableTestSuite;
 
 
 /**
@@ -30,12 +30,10 @@
 
 public class CustomConfigAPITestCase extends CustomConfigTestCase {
 
-
     public CustomConfigAPITestCase(String name) {
         super(name);
     }
 
-
     /**
      * Return the tests included in this test suite.
      */
@@ -48,7 +46,9 @@
         // be able to instantiate it. And this test case must see the same
         // class in order to be able to access its data. Yes this is ugly
         // but the whole jdk14 API is a ******* mess anyway.
-        parent.useSystemLoader("org.apache.commons.logging.jdk14.TestHandler");
+        ClassLoader scl = ClassLoader.getSystemClassLoader();
+        loadTestHandler(HANDLER_NAME, scl);
+        parent.useExplicitLoader(HANDLER_NAME, scl);
         parent.addLogicalLib("commons-logging-api");
 
         PathableClassLoader child = new PathableClassLoader(parent);

Modified: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java?rev=427800&r1=427799&r2=427800&view=diff
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java
 (original)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigFullTestCase.java
 Tue Aug  1 16:48:14 2006
@@ -49,7 +49,9 @@
         // be able to instantiate it. And this test case must see the same
         // class in order to be able to access its data. Yes this is ugly
         // but the whole jdk14 API is a ******* mess anyway.
-        parent.useSystemLoader("org.apache.commons.logging.jdk14.TestHandler");
+        ClassLoader scl = ClassLoader.getSystemClassLoader();
+        loadTestHandler(HANDLER_NAME, scl);
+        parent.useExplicitLoader(HANDLER_NAME, scl);
         parent.addLogicalLib("commons-logging");
 
         PathableClassLoader child = new PathableClassLoader(parent);

Modified: 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigTestCase.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigTestCase.java?rev=427800&r1=427799&r2=427800&view=diff
==============================================================================
--- 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigTestCase.java
 (original)
+++ 
jakarta/commons/proper/logging/trunk/src/test/org/apache/commons/logging/jdk14/CustomConfigTestCase.java
 Tue Aug  1 16:48:14 2006
@@ -18,7 +18,9 @@
 package org.apache.commons.logging.jdk14;
 
 
+import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
+import java.lang.reflect.Method;
 import java.util.Iterator;
 import java.util.logging.Handler;
 import java.util.logging.Level;
@@ -27,7 +29,9 @@
 import java.util.logging.Logger;
 
 import junit.framework.Test;
-import junit.framework.TestSuite;
+
+import org.apache.commons.logging.PathableClassLoader;
+import org.apache.commons.logging.PathableTestSuite;
 
 
 /**
@@ -41,6 +45,8 @@
 
 public class CustomConfigTestCase extends DefaultConfigTestCase {
 
+    protected static final String HANDLER_NAME 
+        = "org.apache.commons.logging.jdk14.TestHandler";
 
     // ----------------------------------------------------------- Constructors
 
@@ -100,6 +106,65 @@
 
 
     /**
+     * Given the name of a class that is somewhere in the classpath of the 
provided
+     * classloader, return the contents of the corresponding .class file.
+     */
+    protected static byte[] readClass(String name, ClassLoader srcCL) throws 
Exception {
+        String resName = name.replace('.', '/') + ".class";
+        System.err.println("Trying to load resource [" + resName + "]");
+        InputStream is = srcCL.getResourceAsStream(resName);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        System.err.println("Reading resource [" + resName + "]");
+        byte[] buf = new byte[1000];
+        for(;;) {
+            int read = is.read(buf);
+            if (read <= 0) {
+                break;
+            }
+            baos.write(buf, 0, read);
+        }
+        is.close();
+        return baos.toByteArray();
+    }
+
+    /**
+     * Make a class available in the system classloader even when its 
classfile is
+     * not present in the classpath configured for that classloader. This only
+     * works for classes for which all dependencies are already loaded in
+     * that classloader.
+     */
+    protected static void loadTestHandler(String className, ClassLoader 
targetCL) {
+        try {
+            targetCL.loadClass(className);
+            // fail("Class already in target classloader");
+            return;
+        } catch(ClassNotFoundException ex) {
+            // ok, go ahead and load it
+        }
+
+        try {
+            ClassLoader srcCL = CustomConfigAPITestCase.class.getClassLoader();
+            byte[] classData = readClass(className, srcCL);
+
+            Class[] params = new Class[] {
+                String.class, classData.getClass(), 
+                Integer.TYPE, Integer.TYPE};
+            Method m = ClassLoader.class.getDeclaredMethod("defineClass", 
params);
+
+            Object[] args = new Object[4];
+            args[0] = className;
+            args[1] = classData;
+            args[2] = new Integer(0);
+            args[3] = new Integer(classData.length);
+            m.setAccessible(true);
+            m.invoke(targetCL, args);
+        } catch(Exception e) {
+            e.printStackTrace();
+            fail("Unable to load class " + className);
+        }
+    }
+
+    /**
      * Set up instance variables required by this test case.
      */
     public void setUp() throws Exception {
@@ -116,18 +181,22 @@
      * Return the tests included in this test suite.
      */
     public static Test suite() throws Exception {
-        /*
-        PathableClassLoader loader = new PathableClassLoader(null);
-        loader.useSystemLoader("junit.");
-
-        PathableClassLoader child = new PathableClassLoader(parent);
-        child.addLogicalLib("testclasses");
-        child.addLogicalLib("commons-logging");
+        PathableClassLoader cl = new PathableClassLoader(null);
+        cl.useExplicitLoader("junit.", Test.class.getClassLoader());
+
+        // the TestHandler class must be accessable from the System classloader
+        // in order for java.util.logging.LogManager.readConfiguration to
+        // be able to instantiate it. And this test case must see the same
+        // class in order to be able to access its data. Yes this is ugly
+        // but the whole jdk14 API is a ******* mess anyway.
+        ClassLoader scl = ClassLoader.getSystemClassLoader();
+        loadTestHandler(HANDLER_NAME, scl);
+        cl.useExplicitLoader(HANDLER_NAME, scl);
+        cl.addLogicalLib("commons-logging");
+        cl.addLogicalLib("testclasses");
         
-        Class testClass = 
child.loadClass(CustomConfigTestCase.class.getName());
-        return new PathableTestSuite(testClass, child);
-        */
-        return new TestSuite(CustomConfigTestCase.class);
+        Class testClass = cl.loadClass(CustomConfigTestCase.class.getName());
+        return new PathableTestSuite(testClass, cl);
     }
 
     /**



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to