微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从 JAR 启动时,ServiceLoader 的工作方式不同

如何解决从 JAR 启动时,ServiceLoader 的工作方式不同

我们使用外部库来生成具有某些特定内容的 pdf 文件。只要我们在 IDE 中将其作为 java 程序运行,一切都会按预期进行。但是,当我们使用 maven-assembly-plugin 构建一个 jar,然后尝试将其作为 JAR 应用程序运行时,就会出现问题。

这是发生了什么。首先,我们在 pom.xml 中包含了两个依赖项:

<dependency>
    <groupId>ch.codeblock.qrinvoice.core</groupId>
    <artifactId>qrinvoice-core</artifactId>
    <version>1.11</version>
</dependency>
<dependency>
    <groupId>ch.codeblock.qrinvoice.openpdf</groupId>
    <artifactId>qrinvoice-openpdf</artifactId>
    <version>1.11</version>
</dependency>

当我们现在调试到问题点时,我们可以看到,它们使用 ServiceLoader 加载可能的 ServiceProviders...

public <T extends Service<?>> List<T> getAll(final Class<T> interfaceType) {
    final List<T> allServiceProviders = new LinkedList<>();
    ServiceLoader.load(interfaceType).iterator().forEachRemaining(allServiceProviders::add);
    return allServiceProviders;
}

... 然后将使用普通的 Java 程序加载 3 个可能的 ServiceProvider:

allServiceProviders = {LinkedList@1397}  size = 3
 0 = {JavaGraphicsOutputWriterFactory@1403} 
 1 = {SvgoutputWriterFactory@1404} 
 2 = {IText4OutputWriterFactory@1405} "IText4OutputWriterFactory"

...但从 JAR 启动时只加载 2 个可能的服务提供者:

allServiceProviders = {LinkedList@1397}  size = 2
 0 = {JavaGraphicsOutputWriterFactory@1403} 
 1 = {SvgoutputWriterFactory@1404} 

现在的问题是,只有 IText4OutputWriterFactory 会打印 pdf,因此从 JAR 运行不起作用。

更深入地查看依赖项表明,该类位于第二个 jar 中:

一个罐子:

第二个罐子:

但是所有类都包含在 jar 中,还有类 ServiceProvider,其中包含 getAll() 方法

组装罐:

那么,这里可能有什么问题?

  • 我们构建 JAR 有什么问题吗?
  • 是否存在某种类路径问题?

我们非常感谢您的帮助!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。