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托管模块-info.java。
module MyService {
exports eu.ngong.myService;
provides eu.ngong.myService.MyService with eu.ngong.myService.ServiceUser;
}用户的个人jar可能是
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.");
}
}使用-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.我错过了什么?
发布于 2021-08-07 14:24:28
需要声明的
使用eu.ngong.myService.MyService;
在要执行服务加载代码的模块中。
如果以自动方式处理,
META-INF/services,以便正确解析jar文件中的模块。因为这不适合于评论,所以在这里分享一个类似例子的发现。在通过IntelliJ执行时,我可以注意到,代码只是与uses声明和user-service模块的类路径一起工作。
此外,我尝试使用类似的命令行:
java --show-module-resolution -p base-service/target/classes:user-service/target/classes --add-modules base.service,user.service -m base.service/base.service.ServiceUser user1
root base.service file://.../base-service/target/classes/
root user.service file://.../user-service/target/classes/
user.service requires base.service file://.../base-service/target/classes/
base.service binds user.service file://.../user-service/target/classes/
...
trying to load user1 environment.
Services found : 2
User1
Default
User1 is acting.并添加了--show-module-resolution,以寻找为什么在模块路径上提供jar不能工作。输出如下,并且在服务模块为not able to bind (用户模块)的地方有不同之处。
java --show-module-resolution -p base-service/target/base-service-1.0-SNAPSHOT.jar:user-service/target/user-service-1.0-SNAPSHOT.jar --add-modules base.service,user.service -m base.service/base.service.ServiceUser user1
root base.service file://...base-service/target/base-service-1.0-SNAPSHOT.jar automatic
root user.service file://...user-service/target/user-service-1.0-SNAPSHOT.jar
user.service requires base.service file://...base-service/target/base-service-1.0-SNAPSHOT.jar automatic
.....
trying to load user1 environment.
Services found : 1
User1
User1 is acting.这也可能是执行方式中意外输出的原因。对于我来说,Default实现的细微差别并没有在后者中得到解决。
https://stackoverflow.com/questions/68691750
复制相似问题