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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26618192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 10:14:54  来源:igfitidea点击:

Install local jar dependency as part of the lifecycle, before Maven attempts to resolve it

javamavenmaven-install-plugin

提问by Wiwiweb

Because of some incompatibilities between two dependencies, I was forced to make a shaded version of one of my dependencies. This means my project now depends on a local .jar file.

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

I was previously perfectly fine with just using mvn install-fileto install this .jar to my local repository, before running mvn install:

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

However, my project will now be on an automated build server, who will only do mvn clean installand nothing else.

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

By looking for a long while, I have found several solutions, but none are perfect.

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

I will be writing down the solutions I found as an answer below, but I'm posting this question hoping that somebody has a better idea to solve this problem.

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

回答by Wiwiweb

Here's the few solutions I tried, but weren't great for my uses:

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

1. maven-install-plugin

1. Maven 安装插件

The idea is to add the install-file goal as part of the install lifecycle by adding this to the pom:

这个想法是通过将以下内容添加到 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>

However, even on the very first goal, validate, Maven will try to resolve dependencies before install-file is run.

然而,即使在第一个目标上,validateMaven 也会在 install-file 运行之前尝试解决依赖关系。

I saw the idea of using the clean goal. Annoyingly, this works when you do separate commands (mvn clean && mvn install) but if you do both in one mvn command (mvn clean install), Maven will resolve dependencies first. Could there be a solution to this?

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

2. Multi Module Project

2. 多模块项目

The idea, seen in this Stack Overflow answer, is that you install-file in your parent pom, and add the dependency in your child pom. Maven will only resolve dependencies separately so this should work.

在这个 Stack Overflow answer 中看到的想法是,您在父 pom 中安装文件,并在您的子 pom 中添加依赖项。Maven 只会单独解析依赖项,所以这应该可以工作。

However my project is a single module, and making a fake parent just to solve this problem seems like an over-complication and an ugly hack.

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

3. System scope with basedir

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>

Although this looks like this was made exactly for this kind of situation, the system scope actually expects the dependency to be on every system where you'll run your project, and so it will not be packaged in the .war, making my project non-functional.

尽管这看起来正是针对这种情况而制作的,但系统范围实际上希望依赖于您将运行项目的每个系统,因此它不会打包在 .war 中,使我的项目非- 功能性的。

4. addjars-maven-plugin

4. addjars-maven-plugin

This custom plugin found hereincludes a .jar in your .war file, then adds it to your pom during compilation.

此处找到的这个自定义插件在您的 .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>

This will work in most normal cases. However, since you don't indicate any dependency to your custom .jar in your actual pom, your IDE will be missing a lot of classes, so you'll need to manually add your custom .jar as an external library.

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

This still is somewhat hacky and does not work with some special cases (hpi:run for Jenkins debugging for example throws some errors). Plus I preferred that my code did not rely on third-party plugins.

这仍然有点笨拙,并且不适用于某些特殊情况(例如,hpi:run for Jenkins 调试会引发一些错误)。另外,我更喜欢我的代码不依赖第三方插件。

5. In-directory Maven repository

5. 目录内 Maven 存储库

I found this solution after creating this post, and I'm pretty happy with it.

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

This is pretty much the same result as doing the mvn install-filecommand in my question, except you save the result and keep it as part of your project by installing the custom library in a repository located inside your project.

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

You will need to pre-install the library using this command.

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

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

Once that's done your repository is created in the lib folder and you won't need to do this command ever again.

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

Indicate that you want to use this repository in your pom:

表明你想在你的 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>

This solution forces you to commit a bunch of extra folders to your SCM, but that was a manageable drawback for me and I'm satisfied with this.

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

回答by bmargulies

Do the shade execution in one subproject (call it S), it eats version (a) of your problem dependency, and produces your own G/A/V'd result. Configure shade to produce the main output of the subproject. In other words, S produces group:artifact:version which are all completely different from the coordinates of the thing you are starting from that you need two version of.

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

In your other subprojects, just declare (S) as the dependency to get the shaded version, and then you can also declare the unshaded other version.

在你的其他子项目中,只要声明(S)作为依赖就可以得到shaded version,然后你也可以声明unshaded other version。

This is all assuming that you renamed the packages when you shaded.

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

There's no need for install:anything.

无需安装:任何东西。

回答by joseaio

Use phase cleanon maven-install-plugin

在 maven-install-plugin 上使用 phase 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>

Execute mvn cleanto install local dependencies before resolution

mvn clean解析前执行安装本地依赖

mvn clean

note: mvn clean installdoesn't work (run clean only)

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