Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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(). Any ideas what might be wrong?

I should add that I am using Java 1.7.0_55-b13 on 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)
    ....
like image 822
user1774051 Avatar asked May 14 '14 09:05

user1774051


1 Answers

I hate to suggest your problem is something so simple, but could pluginsUri be null here? At least in your code snippet, you create a plUri variable but then pass in an unmentioned pluginsUri to ClassLoader.getResources().

From your stack trace, searching for "URLClassPath null pointer exception" uncovered this question which looks to be the same stack trace. In their case the argument to getResources() is clearly null.

Looking at the Java 7 codebase, we see that MetaIndex:243 is:

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

And entry could be null at this line. Looking higher up the stack, entry looks to be the name argument you passed to ClassLoader.getResources().

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

Update: The report is tracked as JDK-8136831, and has been fixed in Java 9.

like image 153
dimo414 Avatar answered Sep 29 '22 11:09

dimo414