gpt4 book ai didi

java - JPMS ServiceLoader 对我不起作用

转载 作者:行者123 更新时间:2023-12-04 14:53:11 25 4
gpt4 key购买 nike

JPMS ServiceLoader 无法正常工作。

我正在尝试提供一个桌面程序作为可执行jar,带有默认服务,可以由个人用户重载。用户提供他们自己的服务类,并在命令行上提供他们的名字作为参数。

服务:

package eu.ngong.myService;

public interface MyService {
public String name();
public void doSomething();
}

程序连同默认服务(插入iffor 的第一行用于日志记录):

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;
}

用户的个人 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.");
}

}

使用 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.

我错过了什么?

最佳答案

  1. 您需要申报

    uses eu.ngong.myService.MyService;

在要执行服务加载代码的模块中。

  1. 尝试确保您的包装添加了 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 实现的细微差别对我来说在后者中没有解决。

关于java - JPMS ServiceLoader 对我不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68691750/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com