我有疑问要构建一个包含所有针对 Java 8 的依赖项的可执行 JAR。最终用户是非开发人员。
其中一个功能是在JavaFx的ImageView组件中显示PDF文件的内容。 PDF 文件中嵌入的一些图像是 jpeg2000。因此,在程序的pom.xml中添加以下依赖项
<dependency>
<groupId>com.github.jai-imageio</groupId>
<artifactId>jai-imageio-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.github.jai-imageio</groupId>
<artifactId>jai-imageio-jpeg2000</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>jbig2-imageio</artifactId>
<version>3.0.0</version>
</dependency>
我的计算机上“.m2”存储库中的类如下所示。
当我在IntelliJ(2024.2.4社区版)中运行该程序时,它运行良好。 PDF 文件中的图像(包括 jpeg2000)显示可以正确查看。
然后我在 pom.xml(IntelliJ 内部)中运行“clean”和“package”,创建了一个 fat-JAR 文件。我检查了 jar 文件中的内容,它看起来如下所示,但路径名不同。
当我运行此可执行 jar 文件并加载嵌入了 jpeg2000 图像的 PDF 文件时,出现错误,日志消息如下。
11/12/2024-09:10:42 ERROR PDFStreamEngine(935) - Cannot read JPEG2000 image: Java Advanced Imaging (JAI) Image I/O Tools are not installed
org.apache.pdfbox.filter.MissingImageReaderException: Cannot read JPEG2000 image: Java Advanced Imaging (JAI) Image I/O Tools are not installed
at org.apache.pdfbox.filter.Filter.findImageReader(Filter.java:172) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.filter.JPXFilter.readJPX(JPXFilter.java:123) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.filter.JPXFilter.decode(JPXFilter.java:72) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.filter.Filter.decode(Filter.java:254) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.cos.COSInputStream.create(COSInputStream.java:73) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.cos.COSStream.createInputStream(COSStream.java:172) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.pdmodel.common.PDStream.createInputStream(PDStream.java:193) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject.createInputStream(PDImageXObject.java:895) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.pdmodel.graphics.image.SampledImageReader.from8bit(SampledImageReader.java:469) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.pdmodel.graphics.image.SampledImageReader.getRGBImage(SampledImageReader.java:217) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject.getImage(PDImageXObject.java:477) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject.getImage(PDImageXObject.java:438) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.rendering.PageDrawer.drawImage(PageDrawer.java:1248) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.contentstream.operator.graphics.DrawObject.process(DrawObject.java:74) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.contentstream.PDFStreamEngine.processOperator(PDFStreamEngine.java:893) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.contentstream.PDFStreamEngine.processStreamOperators(PDFStreamEngine.java:531) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.contentstream.PDFStreamEngine.processStream(PDFStreamEngine.java:506) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.contentstream.PDFStreamEngine.processPage(PDFStreamEngine.java:153) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.rendering.PageDrawer.drawPage(PageDrawer.java:286) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:330) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:247) ~[CoverSheetCreatorFX_new.jar:?]
at org.apache.pdfbox.rendering.PDFRenderer.renderImageWithDPI(PDFRenderer.java:219) ~[CoverSheetCreatorFX_new.jar:?]
在IntelliJ中运行时不会出现此错误。我认为使用 pom.xml 的构建过程会发生一些意外的事情,而 jar 中
com.github.jai-imageio
包的不同路径是根本原因。
顺便说一句,我的电脑上的开发环境使用的是Java 8。
pom.xml 中的“build”部分如下,
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>CoverSheetCreatorFX</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
如果我的猜测是正确的,那么如何在 pom.xml(或其他地方)中解决该问题?
或者如果我的猜测是错误的,那我接下来该怎么办?
我已经下载并检查了前两个依赖项的 JAR 文件,很快发现它们都在
ServiceLoader
包中提供了服务的实现(通过 javax.imageio.spi
加载)。我还没有看到你的汇编文件,但我猜你没有合并 META-INF/services
中的这些文件,而只是覆盖它们(或者更糟糕 - 忽略它们)。这意味着您将错过一些必要的服务。课程在那里,但 ServiceLoader
找不到它们。
我建议您使用 shade 插件,而不是使用程序集插件。它使用其
ServicesResourceTransformer支持
ServiceLoader
文件。
感谢大家的留言。
尝试不同的方法但失败后,我删除了“.m2”文件夹并重建它。新生成的 jar 有不同的行为。在GUI(javaFx)中查看Jpeg2000图像仍然不成功,但能够在后台捕获未发生的错误。这是迄今为止能做到的最好的了。我把它当作一种解决方法。