21

2 つの依存関係の間にいくつかの非互換性があるため、依存関係の 1 つのシェーディング バージョンを作成することを余儀なくされました。これは、私のプロジェクトがローカルの .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

長い間探して、いくつかの解決策を見つけましたが、完璧なものはありません。

以下に答えとして見つけた解決策を書き留めますが、誰かがこの問題を解決するためのより良いアイデアを持っていることを期待して、この質問を投稿しています。

4

3 に答える 3

46

私が試したいくつかの解決策は次のとおりですが、私の用途には適していませんでした。

1.maven-install-プラグイン

アイデアは、これを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場合 ( ) に機能しますが、1 つの mvn コマンドで両方を実行する場合 ( mvn clean install)、Maven が最初に依存関係を解決します。これに対する解決策はありますか?

2. マルチモジュールプロジェクト

この 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-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 を外部ライブラリとして手動で追加する必要があります。

これはまだややハックであり、いくつかの特殊なケースでは機能しません (たとえば、Jenkins デバッグの hpi:run はいくつかのエラーをスローします)。さらに、コードがサードパーティのプラグインに依存しないことを好みました。

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 に大量の余分なフォルダーをコミットする必要がありますが、それは私にとって扱いやすい欠点であり、これには満足しています。

于 2014-10-28T20:49:14.457 に答える
1

1 つのサブプロジェクト (S と呼びます) でシェード実行を行い、問題の依存関係のバージョン (a) を食べて、独自の G/A/V の結果を生成します。サブプロジェクトのメイン出力を生成するように shade を構成します。言い換えれば、S は group:artifact:version を生成しますが、これらはすべて、2 つのバージョンが必要な出発点の座標とはまったく異なります。

他のサブプロジェクトでは、シェーディングされたバージョンを取得する依存関係として (S) を宣言するだけで、シェーディングされていない他のバージョンを宣言することもできます。

これはすべて、シェーディング時にパッケージの名前を変更したことを前提としています。

install:anything は必要ありません。

于 2014-10-29T00:55:47.453 に答える