从 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 (将#修改为@)