2014-05-14 4 views
5

Założę się, że poniższy kod jest bezpieczny, jednak otrzymuję NPE podczas wywoływania hasMoreElements(). Jakieś pomysły, co może być nie tak?Dziwne NPE podczas powtarzania wyniku klasy ClassLoader.getResources()

Należy dodać, że używam języka Java 1.7.0_55-b13 w systemie Windows, 64-bitowy.

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

Ślad stosu:

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

IS nie że 'urlsEn' jest null problem - NPE jest wyrzucany dalej w dół stosu tak to wygląda jak bug .. – assylias

+0

Jaki jest typ programu ładującego klasy kontekstu wątku? –

Odpowiedz

1

Nienawidzę sugerować problem jest coś tak prostego, ale może być nullpluginsUri tutaj? Przynajmniej we fragmencie kodu utworzysz zmienną plUri, ale następnie przekaż ją w niewymienionym pluginsUri do .

Na podstawie śledzenia stosu wyszukano wyrażenie "wyjątek wskaźnika pustego adresu URLClassPath" this question, który wygląda na taki sam. W ich przypadku argument do getResources() jest wyraźnie pusty.

Patrząc na Java 7 codebase widzimy, że MetaIndex:243 jest:

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

I entry może być null na tej linii. Patrząc wyżej na stos, entry wygląda na argument name przekazany do ClassLoader.getResources().

Ten SSCCE:

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

replikuje swój ślad stosu (w Java 8, nie mniej):

$ 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 nie pojawia się określić, co się stanie, jeśli name jest null. Złożyłem błąd sugerujący naprawienie tego zachowania lub przynajmniej wyjaśnienie dokumentacji. Zaktualizuję ten post, jeśli/kiedy Oracle zaakceptuje problem.

Aktualizacja: Raport jest śledzony jako JDK-8136831 i została ustalona w Javie 9.

+0

@ntoskrnl dzięki za aktualizację! – dimo414

Powiązane problemy