2014-05-14 8 views
5

Ich würde annehmen, dass der folgende Code sicher ist, trotzdem bekomme ich eine NPE beim Aufruf hasMoreElements(). Irgendwelche Ideen, was könnte falsch sein?Seltsame NPE beim Iterieren über das Ergebnis von ClassLoader.getResources()

Ich sollte hinzufügen, dass ich Java 1.7.0_55-b13 unter Windows verwenden, 64-Bit.

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); 
    } 
} 

Stapelüberwachung:

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

Das Problem behoben ist nicht, dass 'urlsEn' null ist - der NPE weiter unten in dem Stapel geworfen wird, so dass es aussieht wie ein Fehler .. – assylias

+0

Was ist der Typ Ihres Threadkontextklassenladeprogramms? –

Antwort

1

Ich hasse etwas, das Ihr Problem ist, vorzuschlagen, so einfach, aber pluginsUrinull hier sein könnte? Zumindest in Ihrem Code-Snippet erstellen Sie eine plUri Variable, geben dann aber eine unerwähnte pluginsUri an ClassLoader.getResources() weiter.

Von Ihrem Stack-Trace, die Suche nach "URLClassPath null Zeiger Ausnahme" aufgedeckt this question, die aussieht, um die gleiche Stack-Trace zu sein. In ihrem Fall ist das Argument zu getResources() eindeutig null.

am Java 7 codebase Sehen, sehen wir, dass MetaIndex:243 ist:

if (entry.startsWith(conts[i])) { 

Und entrynull an dieser Linie sein könnte. Mit Blick auf den Stapel nach oben scheint entry das name-Argument zu sein, das Sie an ClassLoader.getResources() übergeben haben.

Diese SSCCE:

public class ClassLoaderNPE { 
    public static void main(String[] args) throws IOException { 
     Enumeration<URL> urls = ClassLoader.getSystemClassLoader().getResources(null); 
     System.out.println(urls.hasMoreElements()); 
    } 
} 

repliziert Ihre Stack-Trace (in Java 8, nicht weniger):

$ 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) 

Die JDK nicht geben scheint, was passiert, wenn namenull ist. Ich habe einen Fehler eingereicht, um vorzuschlagen, dieses Verhalten zu beheben oder zumindest die Dokumentation zu verdeutlichen. Ich werde diesen Beitrag aktualisieren, wenn Oracle das Problem annimmt.

Update: Der Bericht wird als JDK-8136831, verfolgt und hat in Java 9.en

+0

@ntoskrnl danke für das Update! – dimo414