简体   繁体   English

当 Java 期望这种链接约定时,为什么 Maven 在安装本机库时修剪“lib”前缀?

[英]Why does Maven trim the "lib" prefix when installing native libraries when Java expects this convention for linking?

I have been reviving two projects lately involving JNI-based (Java with native libraries) code.我最近一直在恢复两个项目,这些项目涉及基于 JNI(带有本机库的 Java)代码。 The build system is legacy (Makefile based, not Maven or Gradle), but that's ok given the age of the projects (their inception predates Maven), and because some significant parts of the code are not written in Java.构建系统是遗留系统(基于 Makefile,而不是 Maven 或 Gradle),但考虑到项目的年龄(它们的出现早于 Maven),并且因为代码的某些重要部分不是用 Java 编写的,这没关系。

There is no plan for replacing the Makefile (or configure) scripts with Maven or Gradle configuration scripts (the build systems I inherited work fine, and would probably not been made simpler with other tools, given the fact that the softwares are not pure Java).没有计划用 Maven 或 Gradle 配置脚本替换 Makefile(或配置)脚本(我继承的构建系统工作正常,并且可能不会使用其他工具变得更简单,因为这些软件不是纯 Java) .

However, deploying the jars (even built with another tool) in the Maven repo is straightforward with the Maven installation plugin, and makes their use by third party code much simpler, so I went this way.但是,使用 Maven 安装插件在 Maven 存储库中部署 jars(甚至使用其他工具构建)很简单,并且使第三方代码对它们的使用更加简单,所以我采用了这种方式。

I can make everything work, but I have been unable to figure out why Maven (or more specifically, the Maven install plugin) behaves like it does, that seems to make things more complex than they need to be.我可以让一切正常工作,但我一直无法弄清楚为什么 Maven(或更具体地说,Maven 安装插件)的行为如此,这似乎使事情变得比他们需要的更复杂。 Most probably, my understanding of Maven's behaviour or of the Java linking system is lacking.最有可能的是,我缺乏对 Maven 的行为或 Java 链接系统的理解。

Here is the issue: for installing a jar and its native library, one can use the following commands.这是问题所在:要安装 jar 及其本机库,可以使用以下命令。

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)

Here soExtension can be dll , so , dylib depending on the operating system.这里 soExtension 可以是dll , so , dylib取决于操作系统。 The two files end up in the same location of the Maven local repository, namely .m2/repository/groupId/artifactId/versionId这两个文件最终位于 Maven 本地存储库的同一位置,即.m2/repository/groupId/artifactId/versionId

However, I observed that the native library, initially called, say libmylibrary.so , was systematically renamed by Maven mylibrary.so in the repository.但是,我观察到最初称为libmylibrary.so的本机库在存储库中由 Maven mylibrary.so系统地重命名。 As a consequence, even when java is given the proper library path (the -Djava.library.path option), it issues a link error because it cannot find the right library name (it does expect the "lib" prefix, at least in my available implementations).结果,即使为 java 提供了正确的库路径( -Djava.library.path选项),它也会发出链接错误,因为它找不到正确的库名称(它确实需要“lib”前缀,至少在我可用的实现)。

The link error can be solved by several means:链接错误可以通过以下几种方式解决:

  • by renaming the file (trimmed by Maven) back to its correct name通过将文件(由 Maven 修剪)重命名为正确的名称
  • by creating a link afterwards (on systems that support links).通过之后创建链接(在支持链接的系统上)。

The two previous solutions are a rather clumsy way to go, because they assume a knowledge of the internals of the Maven repository (going against the encapsulation principle).前两种解决方案是一种相当笨拙的方法,因为它们假设了解 Maven 存储库的内部结构(违背了封装原则)。

  • another solution is not to rely on Maven, and to install native libraries under the system directories where dynamic libraries are usually expected (LD_LIBRARY_PATH or equivalent).另一种解决方案是不依赖 Maven,并将本机库安装在通常需要动态库的系统目录下(LD_LIBRARY_PATH 或等效项)。 It has been my solution of choice as a last resort, but I find it rather fragile and harder to maintain, since both files (the jar and the native library) are now separated in two different locations.这是我最后选择的解决方案,但我发现它相当脆弱且难以维护,因为两个文件(jar 和本机库)现在都分隔在两个不同的位置。 It also makes the uninstallation of the package more difficult.它也使软件包的卸载更加困难。

Does anyone know why the Maven installation system behave the way it does?有谁知道为什么 Maven 安装系统的行为方式是这样的? And if there is a workaround for it?如果有解决方法?

Thank you谢谢

The name of artifacts in a repository is generated out of artifactId and no there is no possibility to change that.存储库中工件的名称是根据artifactId生成的,并且不可能更改它。 If you like or need to change thatyou have to change the artifactId .如果您喜欢或需要更改,您必须更改artifactId

For running that on a particular platform I would create a kind of installation package which contains the correctly named artifacts.为了在特定平台上运行它,我将创建一种包含正确命名的工件的安装包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM