簡體   English   中英

迭代ClassLoader.getResources()的結果時出現奇怪的NPE

[英]Strange NPE when iterating over result of ClassLoader.getResources()

我假設下面的代碼是安全的,但是我在調​​用hasMoreElements()時得到了一個N​​PE。 什么想法可能是錯的?

我應該補充一點,我在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變量,但隨后將未提及的pluginsUriClassLoader.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)

如果namenullJDK似乎沒有指定會發生什么。 我提交了一個錯誤建議修復此行為,或者至少澄清文檔。 如果/當Oracle接受此問題時,我會更新此帖子。

更新:報告被跟蹤為JDK-8136831 ,並已在Java 9中修復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM