1. ホーム

[解決済み】Mavenの親POMとモジュールPOMの比較

2022-04-02 09:48:27

質問

マルチプロジェクトビルドで親POMを構成する方法はいくつかあるようですが、それぞれの方法の利点と欠点について、どなたか考えをお持ちではないでしょうか。

親Pomを持つ最もシンプルな方法は、プロジェクトのルートに置くことです。

myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

pom.xml は親プロジェクトであると同時に、-core -api と -app モジュールを記述しています。

次の方法は、次のように親を独自のサブディレクトリに分離することです。

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/

親Pomにまだモジュールが含まれているが、相対的なものである場合、例えば ../myproject-core

最後に、モジュールの定義と親を次のように分離するオプションがあります。

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

親 pom にはあらゆる共有設定 (依存関係管理、プロパティなど) が含まれ、myproject/pom.xml にはモジュールのリストが含まれます。

大規模なビルドに対応するため、多数のプロジェクトや成果物に対してスケーラブルであることが望まれます。

おまけ質問です。

  • ソース管理、デプロイメントディレクトリ、共通プラグインなど、様々な共有設定を定義するのに最適な場所はどこでしょうか(親を想定していますが、これに噛んでしまい、共通ではなく各プロジェクトに入ってしまうことがよくあります)。
  • maven-releaseプラグイン、hudson、nexusは、マルチプロジェクトのセットアップ方法にどのように対応していますか(巨大な質問かもしれませんが、マルチプロジェクトのビルドがどのようにセットアップされているかに引っかかった人がいれば、ということです)。

編集:サブプロジェクトはそれぞれ独自のpom.xmlを持っていますが、簡潔さを保つために省きました。

解決方法は?

私の考えでは、この質問に答えるには、プロジェクトのライフサイクルとバージョン管理の観点から考える必要があります。言い換えれば、親Pomは独自のライフサイクルを持っているのか、つまり、他のモジュールとは別にリリースできるのか、そうでないのか、ということです。

もし、その答えが はい (これは質問やコメントで言及されたほとんどのプロジェクトのケースです)、親pomはVCSとMavenの観点から独自のモジュールを必要とし、VCSレベルではこのようなものになります。

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
`-- projectA
    |-- branches
    |-- tags
    `-- trunk
        |-- module1
        |   `-- pom.xml
        |-- moduleN
        |   `-- pom.xml
        `-- pom.xml

このため、チェックアウトが少し面倒になり、その対処法として一般的なのが svn:externals . 例えば trunks ディレクトリを作成します。

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks

以下のようなexternalsの定義で。

parent-pom http://host/svn/parent-pom/trunk
projectA http://host/svn/projectA/trunk

のチェックアウト trunks を実行すると、以下のようなローカル構造になる(パターン2)。

root/
  parent-pom/
    pom.xml
  projectA/

オプションで、さらに pom.xml の中に trunks ディレクトリを作成します。

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks
    `-- pom.xml

これは pom.xml は一種の "fake" pom です。このファイルは決してリリースされないので、本当のバージョンは含まれておらず、モジュールのリストだけが含まれています。このファイルでは、チェックアウトするとこのような構造になります(パターン3)。

root/
  parent-pom/
    pom.xml
  projectA/
  pom.xml

このハックは、チェックアウト後にルートからリアクタービルドを起動し、より便利にするためのものです。実際、私はこの方法でmavenプロジェクトとVCSリポジトリをセットアップして 大規模ビルド うまくいくし、スケールもするし、必要な柔軟性はすべて備えています。

という答えが返ってきたら いいえ (最初の質問に戻りますが)それなら、パターン1(うまくいく可能性のある最も単純なことをする)で我慢できるのではないでしょうか。

さて、ボーナスの質問について。

<ブロッククオート
  • ソース管理、デプロイメントディレクトリ、共通プラグインなど、様々な共有設定を定義するのに最適な場所はどこでしょうか(親を想定していますが、これに噛んでしまい、共通ではなく各プロジェクトに入ってしまうことがよくあります)。

正直、ここで一般的な回答("物事を相互化することに意味があると思うレベルを使う"など)をしない方法がわからないです。いずれにせよ、子ポムは常に継承された設定を上書きすることができます。

  • maven-releaseプラグイン、hudson、nexusは、マルチプロジェクトのセットアップ方法にどのように対応していますか(巨大な質問かもしれませんが、マルチプロジェクトのビルドがどのようにセットアップされているかに引っかかった人がいるかどうかということです)。

私が使っているセットアップはうまくいっていますし、特筆すべきことはありません。

実は、パターン1について、maven-release-pluginはどのように対処しているのでしょうか(特に <parent> セクションは、リリース時にSNAPSHOTの依存関係を持つことができないためです)。これは鶏と卵の問題のように聞こえるが、私はそれが動作するかどうかを覚えていないだけで、テストするのがあまりにも怠惰だった。