I face the problem that the service binding option of jlink links many, many modules, none of them seems to be necessary. These modules aren't linked when the service binding option is omitted.
Questions:
My application: The application is a simple service consisting of an interface, a provider and a consumer, each packed into a separate module, called modService, modProvider, modConsumer (details below).
OS: Windows 10
Jlink without --bind-services
yields the expected result:
jlink --module-path "mods;%JAVA_HOME%\jmods"
--add-modules modConsumer
--output myRuntime
java --list-modules
java.base@9
modConsumer
modService
When the --bind-services
option is applied, I would expect that in addition the module modProvider should be linked. However, see what happens (the three custom modules are at the end):
jlink --module-path "mods;%JAVA_HOME%\jmods"
--bind-services
--add-modules modConsumer
--output myRuntime
java --list-modules
java.base@9
java.compiler@9
java.datatransfer@9
java.desktop@9
java.logging@9
java.management@9
java.management.rmi@9
java.naming@9
java.prefs@9
java.rmi@9
java.scripting@9
java.security.jgss@9
java.security.sasl@9
java.smartcardio@9
java.xml@9
java.xml.crypto@9
jdk.accessibility@9
jdk.charsets@9
jdk.compiler@9
jdk.crypto.cryptoki@9
jdk.crypto.ec@9
jdk.crypto.mscapi@9
jdk.deploy@9
jdk.dynalink@9
jdk.internal.opt@9
jdk.jartool@9
jdk.javadoc@9
jdk.jdeps@9
jdk.jfr@9
jdk.jlink@9
jdk.localedata@9
jdk.management@9
jdk.management.cmm@9
jdk.management.jfr@9
jdk.naming.dns@9
jdk.naming.rmi@9
jdk.scripting.nashorn@9
jdk.security.auth@9
jdk.security.jgss@9
jdk.unsupported@9
jdk.zipfs@9
modConsumer
modProvider
modService
I have no clue why all these modules are linked because the provider just returns a string so that no other jdk module than java.base should be needed.
Below are the Java artifacts:
package test.service;
public interface HelloService {
public String sayHello();
}
package test.provider;
import test.service;
public class HelloProvider implements HelloService {
@Override public String sayHello() { return "Hello!"; }
}
package test.consumer;
import test.service;
import java.util.ServiceLoader;
public class HelloConsumer {
public static void main(String... args) {
ServiceLoader.load(HelloService.class).forEach(s -> System.out.println(s.sayHello()));
}
}
module modService {
exports test.service;
}
module modProvider {
requires modService;
provides test.service.HelloService with test.provider.HelloProvider;
}
module modConsumer {
requires modService;
uses test.service.HelloService;
}
Any help is appreciated.
jlink
so with --bind-services
😉By default jlink
does not bind services, to keep the created runtime as small as possible. That changes with --bind-services
, about which the documentation says
Link service provider modules and their dependencies.
That mirrors the behavior during regular module resolution where, after all dependencies have been resolved, all modules that provide a service used by those modules are included in the readability graph.
The same happens in your case, so all modules providing services used by java.base, modConsumer, and modService are included in the image. As you have found out, that are quite a lot.
If you want to avoid that, you have to forego --bind-services
and instead explicitly list the providers that you want to see in your image:
jlink --module-path "mods;%JAVA_HOME%\jmods"
--add-modules modConsumer,modProvider
--output myRuntime
As stated in the jlink
documentation. The
--bind-services
Link service provider modules and their dependencies.
further, a sample in the same illustrates that the
option will link the modules resolved from root modules with service binding; see the
Configuration.resolveAndBind
method.
From your previous command the root module and the ones resolved in your module graph by default are :
java.base@9
modConsumer
modService
and further, the other modules listed while making use of --bind-services
flag are resolved via the java.base
module.
I would expect that in addition the module
modProvider
should be linked
As suggested by nicolai, you can add the provider module and ensure that it is resolved as well in the module graph.
--add-modules modConsumer,modProvider
Thinking out loud. 1. The current process for finding providers is iterative. 2. Is it possible to specify modules for which one to look for while finding service providers explicitly?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With