我最近正在恢复两个涉及基于 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可以是dll
、so
、dylib
,具体取决于操作系统。
这两个文件最终位于 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/