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). git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/logging/trunk@427800 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -19,8 +19,8 @@ package org.apache.commons.logging.jdk14;
|
|||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
|
|
||||||
import org.apache.commons.logging.PathableTestSuite;
|
|
||||||
import org.apache.commons.logging.PathableClassLoader;
|
import org.apache.commons.logging.PathableClassLoader;
|
||||||
|
import org.apache.commons.logging.PathableTestSuite;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,12 +30,10 @@ import org.apache.commons.logging.PathableClassLoader;
|
|||||||
|
|
||||||
public class CustomConfigAPITestCase extends CustomConfigTestCase {
|
public class CustomConfigAPITestCase extends CustomConfigTestCase {
|
||||||
|
|
||||||
|
|
||||||
public CustomConfigAPITestCase(String name) {
|
public CustomConfigAPITestCase(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the tests included in this test suite.
|
* Return the tests included in this test suite.
|
||||||
*/
|
*/
|
||||||
@@ -48,7 +46,9 @@ public class CustomConfigAPITestCase extends CustomConfigTestCase {
|
|||||||
// be able to instantiate it. And this test case must see the same
|
// 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
|
// class in order to be able to access its data. Yes this is ugly
|
||||||
// but the whole jdk14 API is a ******* mess anyway.
|
// 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");
|
parent.addLogicalLib("commons-logging-api");
|
||||||
|
|
||||||
PathableClassLoader child = new PathableClassLoader(parent);
|
PathableClassLoader child = new PathableClassLoader(parent);
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ public class CustomConfigFullTestCase extends CustomConfigTestCase {
|
|||||||
// be able to instantiate it. And this test case must see the same
|
// 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
|
// class in order to be able to access its data. Yes this is ugly
|
||||||
// but the whole jdk14 API is a ******* mess anyway.
|
// 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");
|
parent.addLogicalLib("commons-logging");
|
||||||
|
|
||||||
PathableClassLoader child = new PathableClassLoader(parent);
|
PathableClassLoader child = new PathableClassLoader(parent);
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
package org.apache.commons.logging.jdk14;
|
package org.apache.commons.logging.jdk14;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.logging.Handler;
|
import java.util.logging.Handler;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -27,7 +29,9 @@ import java.util.logging.LogRecord;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestSuite;
|
|
||||||
|
import org.apache.commons.logging.PathableClassLoader;
|
||||||
|
import org.apache.commons.logging.PathableTestSuite;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,6 +45,8 @@ import junit.framework.TestSuite;
|
|||||||
|
|
||||||
public class CustomConfigTestCase extends DefaultConfigTestCase {
|
public class CustomConfigTestCase extends DefaultConfigTestCase {
|
||||||
|
|
||||||
|
protected static final String HANDLER_NAME
|
||||||
|
= "org.apache.commons.logging.jdk14.TestHandler";
|
||||||
|
|
||||||
// ----------------------------------------------------------- Constructors
|
// ----------------------------------------------------------- Constructors
|
||||||
|
|
||||||
@@ -99,6 +105,65 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
// ------------------------------------------- JUnit Infrastructure Methods
|
// ------------------------------------------- JUnit Infrastructure Methods
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Set up instance variables required by this test case.
|
||||||
*/
|
*/
|
||||||
@@ -116,18 +181,22 @@ public class CustomConfigTestCase extends DefaultConfigTestCase {
|
|||||||
* Return the tests included in this test suite.
|
* Return the tests included in this test suite.
|
||||||
*/
|
*/
|
||||||
public static Test suite() throws Exception {
|
public static Test suite() throws Exception {
|
||||||
/*
|
PathableClassLoader cl = new PathableClassLoader(null);
|
||||||
PathableClassLoader loader = new PathableClassLoader(null);
|
cl.useExplicitLoader("junit.", Test.class.getClassLoader());
|
||||||
loader.useSystemLoader("junit.");
|
|
||||||
|
|
||||||
PathableClassLoader child = new PathableClassLoader(parent);
|
// the TestHandler class must be accessable from the System classloader
|
||||||
child.addLogicalLib("testclasses");
|
// in order for java.util.logging.LogManager.readConfiguration to
|
||||||
child.addLogicalLib("commons-logging");
|
// 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());
|
Class testClass = cl.loadClass(CustomConfigTestCase.class.getName());
|
||||||
return new PathableTestSuite(testClass, child);
|
return new PathableTestSuite(testClass, cl);
|
||||||
*/
|
|
||||||
return new TestSuite(CustomConfigTestCase.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user