I ran into a problem that the option of binding a service to jlink binds many, many modules, none of them seem necessary. These modules are not connected if the service binding option is omitted.
Questions:
- Q1: Do you see the same behavior in your environment?
- Q2: Is this a mistake or a desired behavior?
- Q3: Why are all these modules connected?
My application: the application is a simple service consisting of an interface, a provider and a consumer, each of which is packaged in a separate module called modService, modProvider, modConsumer (see below for more details).
OS: Windows 10
Jlink without --bind-services gives 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 expect the modProvider module to be connected. However, see what happens (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 donβt know why all of these modules are connected, because the provider simply returns a string, so no jdk module other than java.base is needed.
The following are 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.