How does ServiceLoader.load work with class loaders in JPMS?

Tags: , , ,



I have two JPMS layers:

  1. Boot layer with module A loaded by ClassLoaders$AppClassLoader@4fca772d
  2. Child layer with module B that provides cervices and loaded by Loader@6b58b9e9

The parent classloader of Loader@6b58b9e9 is ClassLoaders$AppClassLoader@4fca772d.

In module A I have the following code:

ServiceLoader<ModuleAInterface> sl = ServiceLoader.load(ModuleAInterface.class);

However, the services of Module B are found only when context class loader is Loader@6b58b9e9 and not found when context class loader is ClassLoaders$AppClassLoader@4fca772d.

The question – is it possible to get services of module B in module A without knowing class loader of module B in such configuration.

Answer

looking at the code of java.util.ServiceLoader in jdk 14 (see screenshot) it looks like it follows the same logic as class loading when there are multiple ModuleLayer, as described in this stackoverflow answer

enter image description here

which means that ServiceLoader will will first look at services in its own ModuleLayer then in its parent ModuleLayer and continue from child to parent in a recursive manner

is it possible to get services of module B in module A without knowing class loader of module B in such configuration.

no
but module B can see the services in module A



Source: stackoverflow