简体   繁体   English

迭代ClassLoader.getResources()的结果时出现奇怪的NPE

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

I would assume that the following code is safe, nevertheless I am getting an NPE while invoking hasMoreElements() . 我假设下面的代码是安全的,但是我在调​​用hasMoreElements()时得到了一个N​​PE。 Any ideas what might be wrong? 什么想法可能是错的?

I should add that I am using Java 1.7.0_55-b13 on Windows, 64 bit. 我应该补充一点,我在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);
  }
}

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

I hate to suggest your problem is something so simple, but could pluginsUri be null here? 我讨厌建议你的问题很简单,但是pluginsUri在这里可能是null吗? At least in your code snippet, you create a plUri variable but then pass in an unmentioned pluginsUri to ClassLoader.getResources() . 至少在您的代码片段中,您创建了一个plUri变量,但随后将未提及的pluginsUriClassLoader.getResources()

From your stack trace, searching for "URLClassPath null pointer exception" uncovered this question which looks to be the same stack trace. 从堆栈跟踪中,搜索“URLClassPath空指针异常”发现了这个看起来是相同堆栈跟踪的问题。 In their case the argument to getResources() is clearly null. 在他们的例子中, getResources()的参数显然为null。

Looking at the Java 7 codebase , we see that MetaIndex:243 is: 看看Java 7代码库 ,我们看到MetaIndex:243是:

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

And entry could be null at this line. 并且此行的entry可以为null Looking higher up the stack, entry looks to be the name argument you passed to ClassLoader.getResources() . 在堆栈中向上看, entry看起来是您传递给ClassLoader.getResources()name参数。

This SSCCE : 这个SSCCE

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

replicates your stack trace (in Java 8, no less): 复制堆栈跟踪(在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)

The JDK does not appear specify what happens if name is null . 如果namenullJDK似乎没有指定会发生什么。 I've filed a bug to suggest fixing this behavior, or at least clarifying the documentation. 我提交了一个错误建议修复此行为,或者至少澄清文档。 I'll update this post if/when Oracle accepts the issue. 如果/当Oracle接受此问题时,我会更新此帖子。

Update: The report is tracked as JDK-8136831 , and has been fixed in Java 9. 更新:报告被跟踪为JDK-8136831 ,并已在Java 9中修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM