Update FilteredClassPathRunner so that JUnit rules work

Previously, the tests class and any JUnit annotations it contained were
loaded by a different class loader to JUnit. This meant that the JUnit
annotations were loaded twice and @Rule-annotated fields were not found.
This commit updates FitleredClassPathRunner to use a custom class loader
that ensures that any org.junit.* classes are only loaded by a single
class loader.
pull/6588/merge
Andy Wilkinson 8 years ago
parent df4ef3e1cb
commit 05fc967335

@ -64,8 +64,8 @@ public class FilteredClassPathRunner extends BlockJUnit4ClassRunner {
private URLClassLoader createTestClassLoader(Class<?> testClass) throws Exception { private URLClassLoader createTestClassLoader(Class<?> testClass) throws Exception {
URLClassLoader classLoader = (URLClassLoader) this.getClass().getClassLoader(); URLClassLoader classLoader = (URLClassLoader) this.getClass().getClassLoader();
return new URLClassLoader(filterUrls(extractUrls(classLoader), testClass), return new FilteredClassLoader(filterUrls(extractUrls(classLoader), testClass),
classLoader.getParent()); classLoader.getParent(), classLoader);
} }
private URL[] extractUrls(URLClassLoader classLoader) throws Exception { private URL[] extractUrls(URLClassLoader classLoader) throws Exception {
@ -219,4 +219,23 @@ public class FilteredClassPathRunner extends BlockJUnit4ClassRunner {
} }
private static final class FilteredClassLoader extends URLClassLoader {
private final ClassLoader junitLoader;
FilteredClassLoader(URL[] urls, ClassLoader parent, ClassLoader junitLoader) {
super(urls, parent);
this.junitLoader = junitLoader;
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (name.startsWith("org.junit")) {
return this.junitLoader.loadClass(name);
}
return super.loadClass(name);
}
}
} }

Loading…
Cancel
Save