[英]Strange NPE when iterating over result of ClassLoader.getResources()
我假設下面的代碼是安全的,但是我在調用hasMoreElements()
時得到了一個NPE。 什么想法可能是錯的?
我應該補充一點,我在Windows上使用Java 1.7.0_55-b13,64位。
final List<URL> urls = new ArrayList<URL>();
final String plUri = "META-INF/plugin.xml";
Enumeration<URL> urlsEn =
Thread.currentThread().getContextClassLoader().getResources(pluginsUri);
if (urlsEn != null) {
while (urlsEn.hasMoreElements()) { // NPE happens here
final URL u = urlsEn.nextElement();
urls.add(u);
}
}
堆棧跟蹤:
java.lang.NullPointerException
at sun.misc.MetaIndex.mayContain(MetaIndex.java:243)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:830)
at sun.misc.URLClassPath$2.next(URLClassPath.java:273)
at sun.misc.URLClassPath$2.hasMoreElements(URLClassPath.java:283)
at java.lang.ClassLoader$2.hasMoreElements(ClassLoader.java:1322)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at com.github.jochen.afw.core.guice.GuiceComponentFactoryBuilder.getComponentUrls(GuiceComponentFactoryBuilder.java:256)
at com.github.jochen.afw.core.guice.GuiceComponentFactoryBuilder.build(GuiceComponentFactoryBuilder.java:160)
at com.github.jochen.afw.core.guice.GuiceComponentFactoryBuilderTest.testSuccessfullConfiguration(GuiceComponentFactoryBuilderTest.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
....
我討厭建議你的問題很簡單,但是pluginsUri
在這里可能是null
嗎? 至少在您的代碼片段中,您創建了一個plUri
變量,但隨后將未提及的pluginsUri
給ClassLoader.getResources()
。
從堆棧跟蹤中,搜索“URLClassPath空指針異常”發現了這個看起來是相同堆棧跟蹤的問題。 在他們的例子中, getResources()
的參數顯然為null。
看看Java 7代碼庫 ,我們看到MetaIndex:243
是:
if (entry.startsWith(conts[i])) {
並且此行的entry
可以為null
。 在堆棧中向上看, entry
看起來是您傳遞給ClassLoader.getResources()
的name
參數。
這個SSCCE :
public class ClassLoaderNPE {
public static void main(String[] args) throws IOException {
Enumeration<URL> urls = ClassLoader.getSystemClassLoader().getResources(null);
System.out.println(urls.hasMoreElements());
}
}
復制堆棧跟蹤(在Java 8中,不能少):
$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
$ java -cp . ClassLoaderNPE
Exception in thread "main" java.lang.NullPointerException
at sun.misc.MetaIndex.mayContain(MetaIndex.java:242)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:995)
at sun.misc.URLClassPath$2.next(URLClassPath.java:288)
at sun.misc.URLClassPath$2.hasMoreElements(URLClassPath.java:298)
at java.lang.ClassLoader$2.hasMoreElements(ClassLoader.java:1278)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at ClassLoaderNPE.main(ClassLoaderNPE.java:9)
如果name
為null
, JDK似乎沒有指定會發生什么。 我提交了一個錯誤建議修復此行為,或者至少澄清文檔。 如果/當Oracle接受此問題時,我會更新此帖子。
更新:報告被跟蹤為JDK-8136831 ,並已在Java 9中修復。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.