spring-boot - 在“可执行 JAR”中包含和使用本机 lib 文件(.so、.dylib)
问题描述
我有一个带有 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 文件位于同一目录中才能正常工作。
我试图在项目中使用这个库,但我不能让它工作。我的想法已经不多了,我相信我已经阅读了几乎所有可能的关于这个主题的帖子。
我努力了:
将每个文件加载到 maven repo,将每个文件包含为(dylib、so 和 pdfnet.jar),但会导致错误消息:
Caused by: java.lang.UnsatisfiedLinkError: no PDFNetC in java.library.path:
将所有文件(dylib、so 和 pdfnet.jar)放入 src/main/resources,包括刚刚提供的 PDFNet.jar,但它导致错误消息:
Caused by: java.lang.UnsatisfiedLinkError: no PDFNetC in java.library.path:
唯一可行的方法是当我
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”
解决方案
每个平台只需要两个文件。
PDFNet.jar
适用于所有平台。libPDFNetC.so
对于 LinuxPDFNetC.dll
适用于 WindowsPDFNetC.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
可以指向的位置设置了一些限制,但这应该在您使用的文档提供的文档中。
推荐阅读
- bash - 如何通过提供动态变量并在文本文件中检查它们来在 awk 中显示输出
- android - 在 PHP 中格式化 SMS 消息
- lets-encrypt - 为什么 https 在这个使用 Traefik 的简单反向代理设置中不起作用?
- python - 如何打印整个父节点子结构
- angular - 在 Identity Server 和 OpenId Connect 处于非活动状态后自动注销
- css - Wordress:如何从 CSS 中的博客文章页面中排除类别?
- ios - 从推送通知 iOS Swift 4 中获取值
- javascript - Javascript websocket消息被剪切
- amazon-ec2 - pandoc 错误:数据文件丢失
- google-chrome-app - Chrome 应用程序无法识别的清单键错误