2014-05-14 3 views
5

Suppongo che il seguente codice sia sicuro, tuttavia sto ricevendo un NPE durante il richiamo di hasMoreElements(). Qualche idea su cosa potrebbe essere sbagliato?Strange NPE durante l'iterazione del risultato di ClassLoader.getResources()

Devo aggiungere che sto usando Java 1.7.0_55-b13 su Windows, 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); 
    } 
} 

Stack trace:

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

Il problema non è che il 'urlsEn' è nullo - l'NPE viene gettato più in basso nello stack in modo che appaia come un bug .. – assylias

+0

Qual è il tipo di caricatore della classe di contesto thread? –

risposta

1

Odio suggerire il vostro problema è una cosa così semplice, ma potrebbe essere pluginsUrinull qui? Almeno nel frammento di codice, si crea una variabile plUri ma poi si passa in un numero pluginsUri non codificato a ClassLoader.getResources().

Dalla traccia dello stack, la ricerca di "eccezione puntatore null URLClassPath" è stata rilevata this question che sembra essere la stessa traccia dello stack. Nel loro caso l'argomento a getResources() è chiaramente nullo.

Guardando il Java 7 codebase, vediamo che MetaIndex:243 è:

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

E entry potrebbe essere null a questa linea. Guardando più in alto nello stack, entry sembra essere l'argomento name passato a ClassLoader.getResources().

Questo SSCCE:

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

repliche tuo stack trace (in Java 8, non meno):

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

Il JDK non sembra specificare cosa succede se name è null. Ho presentato un bug per suggerire di correggere questo comportamento o almeno di chiarire la documentazione. Aggiornerò questo post se/quando Oracle accetta il problema.

Update: Il rapporto viene monitorato come JDK-8136831, ed è stato risolto in Java 9.

+0

@ntoskrnl grazie per l'aggiornamento! – dimo414