JDK 9 ServiceLoader bug
Chris Dennis
chris.w.dennis at gmail.com
Thu Mar 16 21:06:09 UTC 2017
Hi All,
I’ve found what I believe could (or should) be considered a bug with the way the ServiceLoader interacts with the classpath in JDK 9. Consider the following code:
====================
package example;
import java.util.ServiceLoader;
public class Main {
public static void main(String[] args) {
ServiceLoader.load(MyService.class).forEach(s -> System.out.println(s + " : " + s.getClass().hashCode()));;
}
}
====================
where MyService is an empty interface and MyServiceImpl is an associated empty implementation. If we JAR the compiled results up with a suitable services declaration and then make two copies of the resultant jar the following behaviors are seen:
[cdennis at Chriss-MacBook-Pro services-test]$ /usr/libexec/java_home -v 1.8 -exec java -showversion -cp one.jar:one.jar example.Main
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
example.MyServiceImpl at 16b98e56 : 2129789493
[cdennis at Chriss-MacBook-Pro services-test]$ /usr/libexec/java_home -v 1.8 -exec java -showversion -cp one.jar:two.jar example.Main
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
example.MyServiceImpl at 16b98e56 : 2129789493
[cdennis at Chriss-MacBook-Pro services-test]$ /usr/libexec/java_home -v 9 -exec java -showversion -cp one.jar:one.jar example.Main
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+159)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+159, mixed mode)
example.MyServiceImpl at 6108b2d7 : 1449621165
[cdennis at Chriss-MacBook-Pro services-test]$ /usr/libexec/java_home -v 9 -exec java -showversion -cp one.jar:two.jar example.Main
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+159)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+159, mixed mode)
example.MyServiceImpl at 6bf256fa : 357863579
example.MyServiceImpl at 1a407d53 : 357863579
Since I’m not using the module path here (and neither of my jars are modular) I would expect to see the same behavior from JDK 9 as I get in 8 (and as is specified in both Javadocs):
"If a particular concrete provider class is named in more than one configuration file, or is named in the same configuration file more than once, then the duplicates are ignored. The configuration file naming a particular provider need not be in the same JAR file or other distribution unit as the provider itself. The provider must be visible from the same class loader that was initially queried to locate the configuration file; note that this is not necessarily the class loader from which the file was actually loaded.”
This will obviously cause confusion for anyone using the ServiceLoader to load singleton services who is not currently in total control of their classpath. Dependencies that are both present and shaded would cause a problem for example.
Thanks,
Chris Dennis
More information about the core-libs-dev
mailing list