【问题标题】:Include and use native lib files (.so, .dylib) in "executable JAR"在“可执行 JAR”中包含和使用本机 lib 文件(.so、.dylib)
【发布时间】:2021-05-02 05:28:51
【问题描述】:

我有一个带有 Maven 的多模块 Spring Boot 项目。我正在使用 spring-boot-maven-plugin 将此应用程序打包到一个可执行的 JAR 中。此 JAR 部署到 PCF(Pivotal Cloud Foundry)。

        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>my.AppMain</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

现在我想使用 PDFTron 库 - 他们为我提供了 JAR 、.so 和 .dylib 文件(也是.dll,但我不需要这些文件)。他们说 JAR 必须与 so 和 dylib 文件位于同一目录中才能正常工作。

我试图在项目中使用这个库,但我不能让它工作。我的想法已经不多了,我相信我已经阅读了几乎所有可能与该主题相关的帖子。

我试过了:

  1. 将每个文件加载到 maven repo,将每个文件包含为(dylib、so 和 pdfnet.jar),但会导致错误消息:Caused by: java.lang.UnsatisfiedLinkError: no PDFNetC in java.library.path:

  2. 将所有文件(dylib、so 和 pdfnet.jar)放入 src/main/resources,包括刚刚提供的 PDFNet.jar,但它导致错误消息:Caused by: java.lang.UnsatisfiedLinkError: no PDFNetC in java.library.path:

  3. 唯一可行的方法是当我使用maven-dependency-plugin 将 PDFTron 依赖项解压缩到目标目录中并更新 -Djava.library.path 以指向这个创建的目录 - 但这可以是仅在我的本地机器上完成,因为 PDFTron 依赖项是在“打包”阶段解包的。对于 PCF,我们只分解可执行 JAR,因此 PCF 中没有目标目录,因此这不是“生产就绪”选项。

我的问题是,我怎样才能将这些文件包含到这个“可执行 JAR”中,这样​​它才能正常工作?有没有办法在运行时解压它们?还是我必须使用spring-boot-maven-plugin以外的其他插件?

我可以在 PCF 修改 -Djava.library.path,但我想避免与这个 JAR 一起部署另一个 zip/jar/文件夹(基本上我想避免更改 CI/ CD 部署脚本,因为它不受我的控制 - 现在我们只部署可执行 JAR)

我使用的是 java 版本“11.0.8”和 spring-boot 版本“2.2.8.RELEASE”

【问题讨论】:

  • 您使用哪个 Java 版本?
  • @khmarbaise 我使用的是 java 版本“11.0.8”和 spring-boot 版本“2.2.8.RELEASE”,我用这个信息更新了问题。

标签: spring-boot maven spring-boot-maven-plugin pdftron


【解决方案1】:

每个平台您只需要两个文件。

  • PDFNet.jar 适用于所有平台。
  • libPDFNetC.so 用于 Linux
  • PDFNetC.dll 适用于 Windows
  • PDFNetC.dylib 用于 macOS

您可以在示例中看到,RuntTest.[sh|exe] 文件显示了您可以使用的设置。例如

#!/bin/sh
TEST_NAME=AddImageTest
javac -cp ../../../Lib/PDFNet.jar *.java
java -Djava.library.path=../../../Lib -cp .:../../../Lib/PDFNet.jar $TEST_NAME

所以-Djava.library.path= 指向包含libPDFNetC.so 和/或PDFNetC.dll 的文件夹。

听起来您的技术堆栈存在特定于部署的问题,但我认为有一种方法,就像您部署任何图像/字体或其他资源的方式一样。尽管您的技术堆栈可能对 java.library.path 可以指向的位置设置了一些限制,但这应该在您使用的文档提供的文档中。

【讨论】:

    猜你喜欢
    • 2011-02-09
    • 1970-01-01
    • 2019-10-04
    • 1970-01-01
    • 2014-10-05
    • 2010-11-15
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多