2014-05-14 44 views
5

我會假設下面的代碼是安全的,但是我在調​​用hasMoreElements()時得到了一個N​​PE。任何想法可能是錯誤的?當迭代ClassLoader.getResources()的結果時奇怪的NPE

我應該補充一點,我在64位Windows上使用Java 1.7.0_55-b13。

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) 
    .... 
+1

不是'urlsEn'爲空的問題 - 所以它看起來像一個NPE進一步拆毀堆棧bug .. – assylias

+0

什麼是你的線程上下文類加載器的類型? –

回答

1

我討厭建議您的問題是這麼簡單的東西,但也pluginsUrinull這裏?至少在您的代碼片段中,您創建了一個plUri變量,但隨後將未提及的pluginsUri傳遞給ClassLoader.getResources()

從您的堆棧跟蹤中,搜索「URLClassPath空指針異常」發現this question看起來是相同的堆棧跟蹤。在他們的情況下,參數getResources()顯然爲空。

望着Java 7 codebase,我們看到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) 

JDK不會出現註明namenull會發生什麼。我提出了一個錯誤來建議修復這種行爲,或者至少澄清文檔。如果/當Oracle接受此問題時,我會更新此帖。

更新:該報告跟蹤爲JDK-8136831,並已固定在Java中9

+0

@ntoskrnl感謝您的更新! – dimo414