【发布时间】:2021-10-11 22:45:33
【问题描述】:
JPMS ServiceLoader 无法正常工作。
我正在尝试提供一个带有默认服务的桌面程序作为可执行 jar,该服务可以由单个用户重载。用户提供自己的服务类,并在命令行中将其名称作为参数提供。
服务:
package eu.ngong.myService;
public interface MyService {
public String name();
public void doSomething();
}
程序连同默认服务(插入if和for的第一行用于记录):
package eu.ngong.myService;
import java.util.ServiceLoader;
public class ServiceUser implements MyService {
private static MyService myService = new ServiceUser();
public static void main(String[] args) {
if (args.length > 0) {
System.out.println("trying to load " + args[0] + " envirionment.");
ServiceLoader<MyService> myServices = ServiceLoader.load(MyService.class);
for (MyService ms : myServices) {
System.out.println(ms.name());
if (ms.name().equalsIgnoreCase(args[0])) {
myService = ms;
}
}
}
myService.doSomething();
}
@Override
public void doSomething() {
System.out.println("The default service is acting.");
}
@Override
public String name() {
return "Default";
}
}
两者都收集在 myService.jar 中,主类 ServiceUser 托管 module-info.java
module MyService {
exports eu.ngong.myService;
provides eu.ngong.myService.MyService with eu.ngong.myService.ServiceUser;
}
用户的个人罐子可能是
package eu.ngong.user1;
import eu.ngong.myService.MyService;
public class User1 implements MyService {
@Override
public String name() {
return "User1";
}
@Override
public void doSomething() {
System.out.println("User1 is acting.");
}
}
使用 module-info.java
module User1 {
requires MyService;
provides eu.ngong.myService.MyService with eu.ngong.user1.User1;
}
但是,运行程序与
java -p ..\user1\user1.jar;myService.jar -jar myService.jar User1
只导致意外输出
trying to load User1 environment.
The default service is acting.
虽然我期望使用日志记录
trying to load User1 environment.
Default
User1
User1 is acting.
我错过了什么?
【问题讨论】:
-
如果你删除“-jar myService.jar”并直接用主类替换它:
eu.ngong.myService.ServiceUser?而且,您是否添加了引用实现的META-INF/eu.ngong.myService.MyService? -
@NoDataFound
-jar与-m应该非常相似。META-INF/services是一个很好的建议,但只要模块被认为是显式的,在我看来也可能不需要。 -
@NoDataFound:切换到 -m 是解决方案的一部分。引用Oracle:使用-jar时,指定的JAR文件是所有用户类的来源
标签: java java-platform-module-system serviceloader