簡體   English   中英

如何使用JUnit在Maven項目中通過自定義類加載器兩次加載同一類

[英]How to load same class by custom classloader twice in Maven project with JUnit

我確實瘋狂了兩個小時,但還是沒什么幫助。

我有一個非常基礎的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無法找到該類,但是為什么呢? 我看到它不在 target/test-classes 我如何在測試時告訴Maven如何將該類放在classpath的src / main / java / some / package / SingletonLazy.java中? 我正在像mvn clean test這樣從命令行執行它

謝謝您的提示!

不要使用SystemClassLoader。 改用立即類加載器。 將您的代碼更改為

InputStream is = SingletonClassLoadedDifferentClassLoadersTestCase.class
      .getClassLoader()
      .getResourceAsStream(className);

我相信JUnit會為每個測試創建一個單獨的類加載器。 我印象深刻的是,JUnit這樣做是為了避免由靜態狀態造成的問題。 我嘗試了幾次測試,發現情況並非如此! 即使您在src/test/java定義了一個類,其靜態狀態也不會被擦除,即該類不會在每次測試中重新加載。

我嘗試過的第二件事是派生測試,但是<forkMode>always</forkMode> ,我認為最高級別的派生僅適用於兩個不同測試類中定義的測試。 如果您在同一類中定義了測試方法,則所有運行的測試方法將使用相同的JVM實例。

靜電本質上是不好的,所以我建議使用控制反轉(IOC)框架。 我過去曾經使用過Guice,它非常輕巧高效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM