在Maven尝试解决之前,将本地jar依赖项作为生命周期的一部分进行安装

由于两个依赖项之间存在一些不兼容性,我被迫制作了一个依赖项的着色版本。 这意味着我的项目现在依赖于本地.jar文件。

在运行mvn install之前,我以前完全没有使用mvn install-file将这个.jar安装到我的本地存储库:

 mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=lib/my-custom-jar-1.0.0.jar mvn install 

但是,我的项目现在将位于一个自动构建服务器上,该服务器将只执行mvn clean install执行任何其他操作。

通过寻找很长一段时间,我找到了几个解决方案,但没有一个是完美的。

我将在下面写下我找到的解决方案作为答案,但我发布这个问题,希望有人有更好的想法来解决这个问题。

这是我尝试过的几个解决方案,但对我的用途并不好:

1. maven-install-plugin

我们的想法是将安装文件目标作为安装生命周期的一部分添加到pom中:

  maven-install-plugin 2.5.2   validate  install-file   lib/my-custom-jar-1.0.0.jar     [...]  org.me my-custom-jar 1.0.0  

但是,即使是第一个目标, validate ,Maven也会尝试在运行install-file之前解析依赖关系。

我看到了使用干净目标的想法。 令人讨厌的是,当你执行单独的命令( mvn clean && mvn install )时,这可以工作,但是如果你在一个mvn命令( mvn clean install )中同时执行这两个命令,Maven将首先解决依赖关系。 可以解决这个问题吗?

2.多模块项目

在这个Stack Overflow答案中看到的想法是你在父pom中安装文件,并在你的孩子pom中添加依赖项。 Maven将仅分别解析依赖关系,因此这应该有效。

然而,我的项目是一个单独的模块,并且只是为了解决这个问题而做一个假的父母似乎是一个过度复杂和丑陋的黑客。

3.系统范围与basedir

  org.me my-custom-jar 1.0.0 system ${basedir}/lib/my-custom-jar-1.0.0.jar  

虽然这看起来完全是出于这种情况,系统范围实际上期望依赖关系在您运行项目的每个系统上,因此它不会打包在.war中,使我的项目非官能的。

4. addjars-maven-plugin

此自定义插件包含.war文件中的.jar,然后在编译时将其添加到您的pom中。

  com.googlecode.addjars-maven-plugin addjars-maven-plugin 1.0.5    add-jars     ${basedir}/lib  **/my-custom-jar-1.0.0.jar        

这适用于大多数正常情况。 但是,由于您没有在实际的pom中指示对自定义.jar的任何依赖性,因此您的IDE将缺少很多类,因此您需要手动将自定义.jar作为外部库添加。

这仍然有点hacky并且不适用于某些特殊情况(hpi:运行Jenkins调试例如抛出一些错误)。 另外,我更喜欢我的代码不依赖于第三方插件。

5.目录内Maven存储库

我在创建这篇文章后找到了这个解决方案,我很满意。

这与在我的问题中执行mvn install-file命令几乎相同,除了保存结果并通过在项目内的存储库中安装自定义库将其保留为项目的一部分。

您需要使用此命令预安装库。

 mvn org.apache.maven.plugins:maven-install-plugin:2.5.1:install-file \ -Dfile=lib/cloudfoundry-client-lib-shaded-1.0.3.jar \ -DlocalRepositoryPath=lib 

完成后,您的存储库将在lib文件夹中创建,您无需再次执行此命令。

表示您要在pom中使用此存储库:

  Local repository file://${basedir}/lib  [...]  org.me my-custom-jar 1.0.0  

这个解决方案迫使你为SCM提交了一堆额外的文件夹,但这对我来说是一个可管理的缺点,我对此感到满意。

在一个子项目中执行阴影执行(称之为S),它会占用问题依赖项的版本(a),并生成您自己的G / A / V结果。 配置阴影以生成子项目的主输出。 换句话说,S产生group:artifact:version,它们与你开始的东西的坐标完全不同,你需要两个版本的。

在您的其他子项目中,只需声明(S)作为获取着色版本的依赖项,然后您还可以声明无阴影的其他版本。

这是假设您在着色时重命名包。

没有必要安装:任何东西。