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

标签 java nullpointerexception classloader

我假设以下代码是安全的,但是我在调​​用 hasMoreElements() 时遇到了 NPE。有什么想法可能是错的吗?

我应该补充一点,我在 Windows 64 位上使用 Java 1.7.0_55-b13。

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 变量,然后将未提及的 pluginsUri 传递给 ClassLoader.getResources()

从您的堆栈跟踪中,搜索“URLClassPath 空指针异常”未发现 this question看起来是相同的堆栈跟踪。在他们的例子中,getResources() 的参数显然为空。

查看 Java 7 codebase ,我们看到 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)

JDK不显示指定如果 namenull 会发生什么。我已经提交了一个错误来建议修复此行为,或者至少澄清文档。如果/当 Oracle 接受这个问题时,我会更新这篇文章。

更新:报告跟踪为JDK-8136831 , 并已在 Java 9 中修复。

关于java - 迭代 ClassLoader.getResources() 的结果时出现奇怪的 NPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23650709/

相关文章:

java - HashMap 到 csv/excel 很容易吗?

java - Kotlin 中内部类的变量阴影 : how variables are resolved?

java - 当 JSON 为 null 时尝试从中提取

java - Android:加载界面时DexClassLoader类加载失败

java - 未找到启动器 Activity !但我已经指定了一个

MainAcitivity setOnClickListener 中的 java.lang.NullPointerException

Android webview 加载数据给出 NullPointerException

java - 是什么导致我的空指针异常

tomcat - 使用类加载器从 tomcat 库实例化 tomcat WEB-INF\class\myclass

java - 脚本修改后部署的 Web 应用程序中发生 Groovy 转换异常