【问题标题】:Why won't the ServiceLoader load any implementations from another module?为什么 ServiceLoader 不会从另一个模块加载任何实现?
【发布时间】:2019-12-17 06:56:50
【问题描述】:

我有一个使用 JPMS 功能的多模块 maven 项目。消费者模块未加载提供者模块中的实现。

这是 maven 项目结构:

ServiceLoaderExample
├── consumer
├── distribution
├── provider
├── service

接口TestService在“服务”模块中定义。实现是TestServiceImpl,它在“provider”模块中定义。而“consumer”模块中的 main() 方法使用 ServiceLoader API 来加载 TestService 的实现。 “分发”模块是我使用 maven-assesmbly-plugin 创建一个包含所有依赖项的 JAR 的地方。

因此,以下是相应的模块信息文件:

1 - “服务”模块(定义org.example.service.TestService):

module org.example.service {
    exports org.example.service;
}

2 - “提供者”模块(定义org.example.provider.TestServiceImpl):

module org.example.provider {
    requires org.example.service;
    provides org.example.service.TestService with org.example.provider.TestServiceImpl;
}

3 - “消费者”模块(它使用 ServiceLoader API 来获取 TestService 的实现):

module org.example.consumer {
    requires org.example.service;
    uses org.example.service.TestService;
}

我正在使用 maven-assesmbly-plugin,因此在构建 JAR 时可能会出现问题。供参考,这是插件定义:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.2.0</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>org.example.consumer.Main</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                </execution>
            </executions>
        </plugin>

我正在使用 Java 13 和 Maven 3.6.3,并且正在使用命令 java -jar distribution-1.0-SNAPSHOT-jar-with-dependencies.jar 运行程序。我做错了什么?

【问题讨论】:

  • TestServiceImpl 是带有 public 无参数构造函数的 public 类吗?
  • @Andreas 是的。
  • 您不能使用 jar-with-dependencies("Uber-jar") 并期望模块和服务正常工作...Modules are strictly 1 module per jar file and support is "Defer to future release"。创建由许多模块组成的单个可分发的“正常”方法是创建一个jlink image
  • 不确定它是否与这个问题相关,但我发现如果模块 A 依赖于模块 B,我可以在模块 A 中制作 ServiceLoader 查看模块 B 中的实现。不完全是我如何定义“插件” -in”,但我确信我缺少一些 Maven 魔法来以某种方式发现和加载模块。 (如果我正确阅读了您的模块定义,那也不是您所做的[将所有内容打包在一个罐子中可以解决该问题],但是正如我所提到的,无论如何都必须这样做似乎都是错误的.. .)

标签: java java-module serviceloader


【解决方案1】:

我无法使用 uber-jar 让它工作,但是,使用 JLink 时一切正常。所以决定只使用 JLink。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    相关资源
    最近更新 更多