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:
- Q1: Do you see the same behavoir in your environment ?
- Q2: Is this a bug or a desired behavoir ?
- Q3: Why all these modules are linked ?
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.