【发布时间】: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