#8 Template method for class loading in AbstractSuiteBuilder

open
nobody
None
5
2005-04-19
2005-04-19
Jon Homan
No

I am using DirectorySuiteBuilder in Eclipse to
create a TestSuite of plugin tests. These tests
reside in a different plugin project from the classes
under test.

Since each plugin has it's own classloader
(EclipseClassLoader), the call to
Class.forName(String) in AbstractSuiteBuilder fails
with the following error:

"Failed to invoke suite():
java.lang.IllegalAccessError: ..."

I propose extracting the call to
Class.forName(String) into a protected template
method that can be overridden. For example:

protected Class loadClass(String className)
throws ClassNotFoundException {
return Class.forName(className);
}

I can then extend DirectorySuiteBuilder and
override this method to use the context
classloader (which is the EclipseClassLoader), and
set the classloader in the suite() method:

public class PluginDirectorySuiteBuilder
extends DirectorySuiteBuilder {

protected Class loadClass(String classname)
throws ClassNotFoundException {
return Class.forName(
classname,
false,
Thread.currentThread().getContextClassLoader());
}

public Test suite(File directory)
throws Exception {

Test suite = null;

ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(
AbstractPluginTestSuite.class.getClassLoader());

suite = super.suite(directory);

} finally {

Thread.currentThread().setContextClassLoader(contextClassLoader);
}

return suite;
}
}

Discussion

  • Jon Homan
    Jon Homan
    2005-04-19

    Patch for AbstractSuiteBuilder.java