[英]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.