首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JPMS ServiceLoader不像预期的那样对我有效。

JPMS ServiceLoader不像预期的那样对我有效。
EN

Stack Overflow用户
提问于 2021-08-07 10:57:01
回答 1查看 153关注 0票数 3

JPMS ServiceLoader不像预期的那样对我起作用。

我试图将桌面程序作为一个可执行的jar提供一个默认服务,该服务可以被单个用户重载。用户提供自己的服务类,并将其名称作为命令行上的参数。

服务

代码语言:javascript
复制
package eu.ngong.myService;

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

程序默认服务( if和for中的第一行插入用于日志记录):

代码语言:javascript
复制
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。

代码语言:javascript
复制
module MyService {
    exports eu.ngong.myService;
    provides eu.ngong.myService.MyService with eu.ngong.myService.ServiceUser;
}

用户的个人jar可能是

代码语言:javascript
复制
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模块。

代码语言:javascript
复制
module User1 {
    requires MyService;
    provides eu.ngong.myService.MyService with eu.ngong.user1.User1;
}

但是,运行程序时

代码语言:javascript
复制
java -p ..\user1\user1.jar;myService.jar -jar myService.jar User1

只导致意外的输出。

代码语言:javascript
复制
trying to load User1 environment.
The default service is acting.

当我期望与日志记录时

代码语言:javascript
复制
trying to load User1 environment.
Default
User1
User1 is acting.

我错过了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-07 14:24:28

需要声明的

使用eu.ngong.myService.MyService;

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

如果以自动方式处理,

  1. 尝试确保您的打包添加了META-INF/services,以便正确解析jar文件中的模块。

因为这不适合于评论,所以在这里分享一个类似例子的发现。在通过IntelliJ执行时,我可以注意到,代码只是与uses声明和user-service模块的类路径一起工作。

此外,我尝试使用类似的命令行:

代码语言:javascript
复制
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 (用户模块)的地方有不同之处。

代码语言:javascript
复制
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实现的细微差别并没有在后者中得到解决。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68691750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档