JDK-8182742 : ClassLoader.getResourceXXX throws NPE when ClassLoader created by defineModulesWithXXX
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.module
  • Affected Version: 9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2017-06-22
  • Updated: 2018-01-17
  • Resolved: 2017-12-06
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10
10 b35Fixed
Related Reports
Relates :  
Description
When creating ServiceLoader with classloader i.e. ServiceLoader<TestService> s = ServiceLoader.load(Class, ClassLoader), 

If the ClassLoader used has no parent classloader , means ClassLoader.parent ==null ,then creation of service loader is working fine but instantiating the providers via stream or iterator breaks with NPE. 

For E.g: 
s.stream().count() // this one breaks. 
for(TestService ts: s) {} // this one breaks too 

======================
java.lang.NullPointerException
	at java.base/jdk.internal.loader.Loader.getResources(Loader.java:422)
	at java.base/jdk.internal.loader.Loader.getResources(Loader.java:422)
	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1190)
	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1215)
	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.access$1200(ServiceLoader.java:1103)
	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator$1.run(ServiceLoader.java:1262)
	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator$1.run(ServiceLoader.java:1261)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1264)
	at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1294)
	at java.base/java.util.ServiceLoader$ProviderSpliterator.tryAdvance(ServiceLoader.java:1478)
...
======================
Comments
The issue indicates as impacting 9 but tck-red-10 label is used. Where the issue is reproduced? in 9?
28-06-2017

The webrev looks good. Only applications creating a new module layer using the new API and specifies with null loader as the parent will be impacted by this issue. It doesn't seem that this issue is a P1. Several SE modules are deprivileged and defined to the platform class loader. If a module layer depends on any of these deprivileged modules, the application has to use platform class loader as the parent when creating a module layer. If the module layer only depends on the modules defined to the null loader, setting the platform class loader as the parent may be one potential workaround for some cases.
27-06-2017

The webrev with a patch for this issue is here: http://cr.openjdk.java.net/~alanb/8182742/webrev/index.html I think we need to decide if this is really a P1 showstopper or not. Understood that it impacts the SL conformance tests. At the same time it is not clear how many applications will create module layers where the class loaders have a null parent.
27-06-2017

I've changed the bug description as this isn't a ServiceLoader bug (but does manifest when using SL).
23-06-2017

This is a regression in jdk-9+175. As part of the last module system update (JDK-8181087), ModuleLayer was updated to specify how resources are located by the class loaders created the defineModulesWithXXX methods. The implementation of getResource, getResources and resources doesn't handle the case that the parent is null. Easy/low-risk fix. If this is a blocker then it will need to be moved to core-libs/java.lang.module and made a P1.
23-06-2017

When creating ServiceLoader with classloader i.e. ServiceLoader<TestService> s = ServiceLoader.load(Class, ClassLoader), If the ClassLoader used has no parent classloader , means ClassLoader.parent ==null ,then creation of service loader is working fine but instantiating the providers via stream or iterator breaks with NPE. For E.g: s.stream().count() // this one breaks. for(TestService ts: s) {} // this one breaks too I am suspecting this to be a JDK issue because the aforementioned behavior is passing in previous JDK build , will confirm with JDK experts whether to raise tck-red-9 and wait for their response.
22-06-2017