在 Maven 尝试解决本地 jar 依赖项之前,在生命周期的一部分安装本地 jar 依赖项1. maven-install-plugin2. 多模块项目3. 系统范围与基础4. addjars-maven-plugin5. 目录内 Maven 存储库

2022-09-02 02:52:39

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

我以前完全没问题,只需使用将此.jar安装到我的本地存储库中,然后再运行:mvn install-filemvn 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

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

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


答案 1

以下是我尝试过的一些解决方案,但不适合我的使用:

1. maven-install-plugin

我们的想法是通过将安装文件目标添加到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>

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

我看到了使用干净目标的想法。令人讨厌的是,当您执行单独的命令()时,这有效,但是如果您在一个mvn命令()中同时执行这两个命令,Maven将首先解析依赖项。有没有一个解决方案?mvn clean && mvn installmvn clean install

2. 多模块项目

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

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

3. 系统范围与基础

<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-maven-plugin

此处的这个自定义插件在 .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添加为外部库。

这仍然有点黑客,并且不适用于一些特殊情况(例如,hpi:run for 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 中使用此存储库:

<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,但这对我来说是一个可管理的缺点,我对此感到满意。


答案 2

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

在其他子项目中,只需将 (S) 声明为依赖项即可获取着色版本,然后还可以声明未着色的其他版本。

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

不需要安装:任何东西。


推荐