java如何在带有JUnit的Maven项目中通过自定义类加载器两次加载同一类
两个小时后,我真是疯了,但到目前为止,一切都无济于事
我有一个非常基本的Maven项目,我有一些单例类。据说可以用不同的类加载器加载singleton两次,所以我写了自己的类加载器,但问题是我无法加载该类,因为我得到了ClassNotFoundException,但我不知道为什么
@RunWith(JUnit4.class)
public class SingletonClassLoadedDifferentClassLoadersTestCase {
static class SingletonClassLoader extends ClassLoader {
@Override
public Class<?> loadClass(String className)
throws ClassNotFoundException {
try {
InputStream is =
// seems to be the central problem
ClassLoader.getSystemResourceAsStream(className);
if (is == null) {
throw new ClassNotFoundException();
}
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[1024];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
byte[] classBytes = buffer.toByteArray();
return defineClass(className, classBytes, 0, classBytes.length);
} catch (IOException ex) {
throw new ClassNotFoundException();
}
}
}
@Test
public void singletonTest() throws Exception {
Class<?> singleton1 = new SingletonClassLoader()
.loadClass("SingletonLazy");
Class<?> singleton2 = new SingletonClassLoader()
.loadClass("SingletonLazy");
}
}
SingletonLazy
只是src/main/java中的一个类(隐藏在某些包目录中)。似乎ClassLoader找不到那个类,但为什么呢?我看到它在{mvn clean test
谢谢你的提示
# 1 楼答案
不要使用SystemClassLoader。改用即时类加载器。将代码更改为
我相信JUnit会为每个测试创建一个单独的类加载器。我的印象是JUnit这样做是为了避免静态产生的问题。我尝试了一些测试,但我发现事实并非如此!即使您在
src/test/java
中定义了一个类,它的静态状态也不会被擦除,也就是说,每个测试都不会重新加载该类我尝试的第二件事是分叉测试,但我相信最高级别的分叉只适用于在两个不同测试类中定义的测试。如果在同一个类中定义了测试方法,那么所有测试方法运行都将使用相同的JVM实例
静态本质上是不好的,所以我建议使用控制反转(InversionofControl,IOC)框架。我过去使用过Guice,它非常轻量级和高效