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

时间:2014-10-28 20:49:14

标签: java maven maven-install-plugin

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

我以前完全没问题,只需使用mvn install-file将此.jar安装到我的本地存储库,然后再运行mvn install

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而不会执行任何操作。

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

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

3 个答案:

答案 0 :(得分:34)

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

1。行家安装-插件

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

<plugin>
  <artifactId>maven-install-plugin</artifactId>
  <version>2.5.2</version>
  <executions>
    <execution>
      <phase>validate</phase>
      <goals>
        <goal>install-file</goal>
      </goals>
      <configuration>
        <file>lib/my-custom-jar-1.0.0.jar</file>
      </configuration>
    </execution>
  </executions>
</plugin>

[...]

<dependency>
  <groupId>org.me</groupId>
  <artifactId>my-custom-jar</artifactId>
  <version>1.0.0</version>
</dependency>

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

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

2。多模块项目

这个想法seen in this Stack Overflow answer是你在父pom中安装文件,并在你的孩子pom中添加依赖项。 Maven将只分别解决依赖关系,因此这应该有效。

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

3。系统范围与basedir

<dependency>
  <groupId>org.me</groupId>
  <artifactId>my-custom-jar</artifactId>
  <version>1.0.0</version>
  <scope>system</scope>
  <systemPath>${basedir}/lib/my-custom-jar-1.0.0.jar</systemPath>
</dependency>

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

4。 addjars-行家-插件

This custom plugin found here在.war文件中包含.jar,然后在编译时将其添加到您的pom中。

<plugin>
  <groupId>com.googlecode.addjars-maven-plugin</groupId>
  <artifactId>addjars-maven-plugin</artifactId>
  <version>1.0.5</version>
  <executions>
    <execution>
      <goals>
        <goal>add-jars</goal>
      </goals>
      <configuration>
        <resources>
          <resource>
            <directory>${basedir}/lib</directory>
            <includes>
              <include>**/my-custom-jar-1.0.0.jar</include>
            </includes>
          </resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>

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

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

5。目录内Maven存储库

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

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

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

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中使用此存储库:

<repository>
  <id>Local repository</id>
  <url>file://${basedir}/lib</url>
</repository>

[...]

<dependency>
  <groupId>org.me</groupId>
  <artifactId>my-custom-jar</artifactId>
  <version>1.0.0</version>
</dependency>

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

答案 1 :(得分:1)

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

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

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

无需安装:任何事情。

答案 2 :(得分:0)

在maven-install-plugin上使用阶段 clean

<plugin>
  <artifactId>maven-install-plugin</artifactId>
  <version>2.5.2</version>
  <executions>
    <execution>
      <phase>**clean**</phase>
      <goals>
        <goal>install-file</goal>
      </goals>
      <configuration>
        <file>lib/my-custom-jar-1.0.0.jar</file>
      </configuration>
    </execution>
  </executions>
</plugin>

执行mvn clean以在解决方案之前安装本地依赖项

mvn clean

注意:mvn clean install不起作用(仅运行干净)