java - 当 Java 需要这种链接约定时,为什么 Maven 在安装 native 库时会修剪 "lib"前缀?

标签 java maven java-native-interface native maven-install-plugin

我最近正在恢复两个涉及基于 JNI(带有 native 库的 Java)代码的项目。构建系统是遗留的(基于 Makefile,而不是 Maven 或 Gradle),但是考虑到项目的年龄(它们的开始早于 Maven),并且代码的一些重要部分不是用 Java 编写的,这没关系。

没有计划用 Maven 或 Gradle 配置脚本替换 Makefile(或配置)脚本(我继承的构建系统运行良好,并且可能不会使用其他工具变得更简单,因为这些软件不是纯Java)。

但是,使用 Maven 安装插件在 Maven 存储库中部署 jar(甚至使用其他工具构建)非常简单,并且使第三方代码的使用变得更加简单,所以我采用了这种方式。

我可以让一切正常工作,但我一直无法弄清楚为什么 Maven(或更具体地说,Maven 安装插件)的行为如此,这似乎使事情变得比他们需要的更复杂。最有可能的是,我对 Maven 的行为或 Java 链接系统缺乏了解。

问题是:要安装 jar 及其 native 库,可以使用以下命令。

mvn install:install-file -Dfile=$(jarFile) -DgroupId=$(groupId) -DartifactId=$(artifactId) -Dversion=$(libraryVersion) -Dpackaging=jar

mvn install:install-file -Dfile=$(nativeLibraryFile) -DgroupId=$(groupId) -DartifactId=$(artifactId) -Dversion=$(libraryVersion) -Dpackaging=$(soExtension)

这里soExtension可以是dllsodylib,具体取决于操作系统。 这两个文件最终位于 Maven 本地存储库的同一位置,即 .m2/repository/groupId/artifactId/versionId

但是,我观察到最初称为 libmylibrary.so 的 native 库已由存储库中的 Maven mylibrary.so 系统地重命名。因此,即使为 java 提供了正确的库路径(-Djava.library.path 选项),它也会发出链接错误,因为它找不到正确的库名称(它确实期望“lib"前缀,至少在我可用的实现中)。

链接错误可以通过多种方式解决:

  • 通过将文件重命名(由 Maven 修剪)回正确的名称
  • 随后创建链接(在支持链接的系统上)。

前面的两个解决方案是一种相当笨拙的方法,因为它们假设了解 Maven 存储库的内部结构(违背了封装原则)。

  • 另一个解决方案是不依赖 Maven,并将 native 库安装在通常需要动态库的系统目录下(LD_LIBRARY_PATH 或等效目录)。这是我作为最后手段选择的解决方案,但我发现它相当脆弱且难以维护,因为两个文件(jar 和 native 库)现在分开在两个不同的位置。它还使软件包的卸载变得更加困难。

有谁知道为什么 Maven 安装系统会这样?如果有解决方法吗?

谢谢

最佳答案

存储库中 Artifact 的名称是根据 artifactId 生成的,并且不可能更改它。如果您喜欢或需要更改,则必须更改 artifactId

为了在特定平台上运行它,我将创建一种安装包,其中包含正确命名的 Artifact 。

关于java - 当 Java 需要这种链接约定时,为什么 Maven 在安装 native 库时会修剪 "lib"前缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72521873/

相关文章:

分层多模块项目的 Maven 命名约定

android - Android Studio 中的代码分享

java - 调用 C 子例程时出现 JNI 错误

c# - 从 Java 调用 C# 代码?

java - 如何使用 maven 为特定文件夹创建额外的 JAR

java - 在 Android 上使用 System.load?

java - devserver 中的 google 端点上出现 404

java - 无法从 spring mvc portlet 中的 View 检索模型属性

java - 多对多关系的属性 (Hibernate)

java - 在使用执行器服务创建的线程中使用声明性事务