web-dev-qa-db-ja.com

Mavenおよび依存モジュール

同僚はmavenとその魔法の依存関係の素晴らしさを称賛してきましたが、明らかな使用法と考えるもので失敗することがわかりました。

マスターPOMを持つルートフォルダーがあるとします。

その後、私はいくつかのプロジェクトを持っています、それらをAとBと呼びます

BはAを必要とするため、BフォルダーのPOMには適切な依存関係エントリが含まれています

次に、ルートフォルダーに戻り、プロファイルで、Bをビルドすることを指定します。

通常のmvn clean installを実行すると、Aがビルドされていないため失敗します。

友人は、ルートのメインプロファイルでAとBの両方を指定する必要があると言っています。

しかし、MavenがBを見る依存関係管理のポイントではなく、B POMファイルに移動し、そこでAの依存関係を確認するため、Aを自動的にビルドする必要があります。

50
David

希望する動作が実装されていないと考えられる理由は次のとおりです。

私がプロジェクトAとBの両方に取り組んでいるとします。現在、Aは壊れています。依存関係の解決が希望どおりに行われた場合、Aが修正されるまでBをビルドすることはできません。そのため、Aへの変更をロールバックするか、最初にAの修正に集中する必要があります。いずれにせよ、私が今焦点を合わせたいものではないかもしれません。

一般的に、Bは最新ではなく、「最後の良い」バージョンのAを使用したいと考えています。リポジトリから依存関係を使用するということは、少なくともそれらが正常にコンパイルされたことを意味します(そして、できれば単体テストも実行されたことを願っています)。

25
Rich Seller

マスターPOMの場合:

~/scratch/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>scratch</groupId>
    <artifactId>scratch</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>nipple</module>
        <module>cabbage</module>
    </modules>
</project>

モジュールPOM:

~/scratch/nipple/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <artifactId>scratch</artifactId>
        <groupId>scratch</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <groupId>scratch</groupId>
    <artifactId>nipple</artifactId>
    <version>1.0-SNAPSHOT</version>

</project>

~/scratch/cabbage/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <artifactId>scratch</artifactId>
        <groupId>scratch</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <groupId>scratch</groupId>
    <artifactId>cabbage</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>scratch</groupId>
            <artifactId>nipple</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

ローカルリポジトリをクリアした後、ルートディレクトリでmvn packageを発行すると、すべてのモジュールがビルドされます。 (空っぽのJARに、ただしビルドされています。)

Mavenは、リポジトリまたはビルド進行中のいずれかで依存関係を探しているようです。単一のモジュールのみをビルドしている場合、プロジェクト構造を自動的に走査することはありません。これは、現在のモジュールの1つ上のディレクトリよりもはるかに少ない、親プロジェクトをコンピューターに配置する必要もないためです。 (親子関係は全単射でさえありません。)

これがそうなる理由は、モジュールの場所が予測可能なディレクトリレイアウトが決して必須ではないためかもしれません。上記の例のレイアウトが次のようなものであることは、いくぶん一般的で受け入れられます。

projects
|
+--scratch
|  |
|  +--scratch-parent
|  |  |
|  |  +--pom.xml [The POM of scratch:scratch:1.0-SNAPSHOT]
|  |
|  +--nipple
|  |  |
|  |  +--pom.xml [The POM of scratch:mod1:1.0-SNAPSHOT]
|  |
|  +--cabbage
|  |  |
|  |  +--pom.xml [The POM of scratch:mod2:1.0-SNAPSHOT]

この場合、親POMの<modules>セクションは次のようになります。

<modules>
    <module>../nipple</module>
    <module>../cabbage</module>
</modules>

whichアーティファクトIDがどのモジュールにあるかということは何もありません。これは、これらがこのビルドに関連する他のアーティファクトを検索するファイルシステムの場所であることをMavenに伝える役割を果たします。

42
millimoose

Mavenリアクタープラグイン 、特にreactor:makeを見てください。これはモジュールとそれが依存するすべてのモジュールをビルドします。

14
deterb

リッチはまったく正しい。あなたが説明することは、一般的に期待される動作ではありません。 deterbで述べられているように、Mavenリアクターは部分ビルドをサポートしています親POMがモジュールを認識している場合

mvn install -pl B -amする必要がありますまたmake-am)Bの依存関係(つまり、A)。

とにかく、モジュールA mustは親POMのモジュールです。

Mavenモジュール+単一の特定モジュールのビルド を参照)

5
mmuller

IntelliJを使用している場合、Mavenの実行構成に「ワークスペースアーティファクトの解決」という小さな魔法のチェックボックスがあります。したがって、親からインストールしたりビルドしたりする必要はありません。

4
Tomer

答えは、Mavenの動作ではないということだけです。 Mavenの背後にある考え方は、開発者に依存関係を制御するための論理的でシンプルなシステムを提供することです。リポジトリから依存関係を取得することがこれの鍵です。すべての例外は、この制御と単純さを弱めます。親POMに依存関係としてAを追加すると、さらに例外を追加することなく、シナリオに完全に対応できます。シナリオに対処する別の方法は、バッチファイルまたはantスクリプトを使用することです。

3
T Rob Darrough