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@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@16b98e56 : 2129789493
[cdennis@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@16b98e56 : 2129789493
[cdennis@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@6108b2d7 : 1449621165
[cdennis@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@6bf256fa : 357863579
example.MyServiceImpl@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