Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在使用JUnit的Maven项目中,如何通过自定义类加载器两次加载同一类_Java_Maven_Junit_Singleton - Fatal编程技术网

Java 在使用JUnit的Maven项目中,如何通过自定义类加载器两次加载同一类

Java 在使用JUnit的Maven项目中,如何通过自定义类加载器两次加载同一类,java,maven,junit,singleton,Java,Maven,Junit,Singleton,两个小时后,我真是疯了,但到目前为止,一切都无济于事 我有一个非常基本的Maven项目,我有一些单例类。据说可以用不同的类加载器加载singleton两次,所以我写了自己的类加载器,但问题是我无法加载该类,因为我得到了ClassNotFoundException,但我不知道为什么 @RunWith(JUnit4.class) public class SingletonClassLoadedDifferentClassLoadersTestCase { static class Sin

两个小时后,我真是疯了,但到目前为止,一切都无济于事

我有一个非常基本的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");
    }
}
@RunWith(JUnit4.class)
公共类SingletonClassLoadedDifferentintClassLoaderTestCase{
静态类SingletonClassLoader扩展了ClassLoader{
@凌驾
公共类loadClass(字符串类名称)
抛出ClassNotFoundException{
试一试{
输入流是=
//这似乎是核心问题
ClassLoader.getSystemResourceAsStream(类名称);
如果(is==null){
抛出新的ClassNotFoundException();
}
ByteArrayOutputStream缓冲区=新建ByteArrayOutputStream();
国际nRead;
字节[]数据=新字节[1024];
而((nRead=is.read(data,0,data.length))!=-1){
写入(数据,0,nRead);
}
byte[]classBytes=buffer.toByteArray();
返回defineClass(className,classBytes,0,classBytes.length);
}捕获(IOEX异常){
抛出新的ClassNotFoundException();
}
}
}
@试验
public void singletonTest()引发异常{
类singleton1=新的SingletonClassLoader()
.loadClass(“SingletonLazy”);
类singleton2=新的SingletonClassLoader()
.loadClass(“SingletonLazy”);
}
}
SingletonLazy
只是src/main/java中的一个类(隐藏在一些包目录中)。似乎ClassLoader找不到那个类,但为什么呢?我看到它不在
目标/测试类中。当我进行测试时,如何告诉Maven以某种方式将该类放在类路径上的src/main/java/some/package/SingletonLazy.java中?我正在从命令行执行它,如
mvn clean test


谢谢你的提示

不要使用SystemClassLoader。改用即时类加载器。将代码更改为

InputStream is = SingletonClassLoadedDifferentClassLoadersTestCase.class
      .getClassLoader()
      .getResourceAsStream(className);
我相信JUnit会为每个测试创建一个单独的类加载器。我的印象是JUnit这样做是为了避免静态产生的问题。我尝试了一些测试,但我发现事实并非如此!即使您在
src/test/java
中定义了一个类,它的静态状态也不会被擦除,也就是说,每个测试都不会重新加载该类

我尝试的第二件事是分叉测试,但
总是
,我相信最高级别的分叉只适用于在两个不同测试类中定义的测试。如果在同一个类中定义了测试方法,那么所有测试方法运行都将使用相同的JVM实例


静态本质上是不好的,所以我建议使用控制反转(InversionofControl,IOC)框架。我以前使用过Guice,它非常轻量级和高效。

在您的代码中仍然为空。我想知道,类加载器究竟从哪里搜索类。我真的不知道。因此,该类位于src/test/java/some/package/TestCase.java中,SingletonLazy.java位于src/main/java/some/pkg/SingletonLazy.java中,编译后,SingletonLazy.class位于target/class/some/package/SingletonLazy.class中,而这一点根本没有被发现。