web-dev-qa-db-ja.com

Maven親POMとモジュールPOM

マルチプロジェクトビルドで親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には「共有」構成(dependencyManagement、プロパティなど)が含まれ、myproject/pom.xmlにはモジュールのリストが含まれます。

その目的は、大規模なビルドに合わせてスケーラブルにすることであるため、多数のプロジェクトや成果物に合わせてスケーラブルにする必要があります。

いくつかのボーナス質問:

  • ソース管理、展開ディレクトリ、一般的なプラグインなど、さまざまな共有構成を定義するのに最適な場所はどこですか(親を想定していますが、これにしばしば噛まれ、各プロジェクトではなく各プロジェクトに行き着きました一般的なもの)。
  • Maven-releaseプラグイン、hudson、およびnexusは、マルチプロジェクトのセットアップ方法をどのように処理しますか(おそらく大きな質問です。マルチプロジェクトビルドのセットアップ方法によって誰かが発見された場合、それはさらに重要です)。

編集:各サブプロジェクトには独自のpom.xmlがありますが、簡潔にするために省略しました。

276
Jamie McCrindle

私の意見では、この質問に答えるためには、プロジェクトのライフサイクルとバージョン管理の観点から考える必要があります。言い換えると、親POMには独自のライフサイクルがありますか?つまり、他のモジュールとは別にリリースできますか?

答えがyesである場合(これは質問またはコメントで言及されているほとんどのプロジェクトの場合)、親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

次の外部定義を使用します。

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

trunksをチェックアウトすると、次のローカル構造になります(パターン#2):

root/
  parent-pom/
    pom.xml
  projectA/

オプションで、trunksディレクトリにpom.xmlを追加することもできます。

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は一種の「偽の」pomです。リリースされることはありません。このファイルはリリースされないため、実際のバージョンは含まれません。モジュールのリストのみが含まれます。このファイルでは、チェックアウトの結果、次の構造になります(パターン#3):

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

この「ハック」により、チェックアウト後にルートからリアクタービルドを起動し、さらに便利になります。実際、これはラージビルドのmavenプロジェクトとVCSリポジトリをセットアップする方法です:動作するだけでなく、拡張性もあり、必要な柔軟性をすべて提供します。

答えがno(最初の質問に戻る)の場合、パターン#1(おそらく動作する可能性のある最も単純なこと)で生きることができると思います。

次に、ボーナスの質問について:

  • ソース管理、展開ディレクトリ、一般的なプラグインなど、さまざまな共有構成を定義するのに最適な場所はどこですか(親を想定していますが、これにしばしば噛まれ、各プロジェクトではなく各プロジェクトに行き着きました一般的なもの)。

正直なところ、私はここで一般的な答えを出さない方法を知りません(「物事を相互化するのに意味があると思うレベルを使用する」など)。とにかく、子pomsは常に継承された設定をオーバーライドできます。

  • Maven-releaseプラグイン、hudson、およびnexusは、マルチプロジェクトのセットアップ方法をどのように処理しますか(おそらく大きな質問です。マルチプロジェクトビルドのセットアップ方法によって誰かが発見された場合、それはさらに重要です)。

言うまでもなく、私が使用するセットアップはうまく機能します。

実際、maven-release-pluginがパターン#1(特に、リリース時にSNAPSHOT依存関係を持つことができないため、<parent>セクションを処理する方法)を疑問に思います。これは鶏肉または卵の問題のように聞こえますが、それが機能していてテストするには遅すぎるかどうか覚えていません。

163
Pascal Thivent

私の経験とMavenのベストプラクティスから、2種類の「親ポン」があります

  • 「会社」の親ポン-このポンには、すべてのポンを継承する会社固有の情報と設定が含まれており、コピーする必要はありません。これらの情報は次のとおりです。

    • リポジトリ
    • 配布管理セクション
    • 一般的なプラグイン構成(maven-compiler-pluginソースおよびターゲットバージョンなど)
    • 組織、開発者など

    すべての会社のPOMはそれを継承するため、この親POMの準備は慎重に行う必要があります。そのため、このPOMは成熟して安定している必要があります(親POMのバージョンをリリースしても、すべての会社のプロジェクトのリリースに影響することはありません!)

  • 2番目の種類の親pomは、マルチモジュールの親です。私はあなたの最初の解決策を好みます-これはマルチモジュールプロジェクトのデフォルトのMaven規約であり、非常に頻繁にVCSコード構造を表します

その目的は、大規模なビルドに合わせてスケーラブルにすることであるため、多数のプロジェクトや成果物に合わせてスケーラブルにする必要があります。

Mutliprojectsにはツリー構造があります。そのため、親レベルの1レベルに移動する必要はありません。ニーズに合った適切なプロジェクト構造を見つけてみてください-古典的な例は、マルチモジュールプロジェクトを区別する方法です

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

いくつかのボーナス質問:

  • ソース管理、展開ディレクトリ、一般的なプラグインなど、さまざまな共有構成を定義するのに最適な場所はどこですか(親を想定していますが、これにしばしば噛まれ、各プロジェクトではなく各プロジェクトに行き着きました一般的なもの)。

この構成は、賢明に「会社」の親ポンとプロジェクトの親ポンに分割する必要があります。あなたがプロジェクトするすべてに関連するものは「会社」の親に行き、これは現在のプロジェクトに関連するものがプロジェクトのものに行く。

  • Maven-releaseプラグイン、hudson、およびnexusは、マルチプロジェクトのセットアップ方法をどのように処理しますか(おそらく大きな質問です。マルチプロジェクトビルドのセットアップ方法によって誰かが発見された場合、それはさらに重要です)。

会社の親ポンを最初にリリースする必要があります。マルチプロジェクトの場合、標準ルールが適用されます。 CIサーバーは、プロジェクトを正しくビルドするためにすべてを知る必要があります。

33
cetnar
  1. 独立した親は、それ以外の場合は結合されていないコンポーネント間で構成とオプションを共有するためのベストプラクティスです。 Apacheには、法的通知といくつかの一般的なパッケージオプションを共有する親pomプロジェクトがあります。

  2. 最上位プロジェクトにjavadocの集約やリリースのパッケージ化などの実際の作業がある場合、その作業を行うために必要な設定と、親を介して共有したい設定との間に矛盾が生じます。親のみのプロジェクトはそれを避けます。

  3. 一般的なパターン(現時点では#1を無視)では、コード付きプロジェクトで親プロジェクトを親として使用し、トップレベルを親として使用します。これにより、すべてのものでコアなものを共有できますが、#2で説明した問題は回避されます。

  4. 親構造がディレクトリ構造と同じでない場合、サイトプラグインは非常に混乱します。集約サイトを構築する場合は、これを回避するためにいくつかの操作を行う必要があります。

  5. Apache CXF は、#2のパターンの例です。

22
bmargulies

3番目のアプローチには、ちょっとした問題があります。集約POM(myproject/pom.xml)は通常、親をまったく持たないため、構成を共有しません。つまり、これらすべての集約POMにはデフォルトのリポジトリのみが含まれることになります。

Centralのプラグインのみを使用している場合は問題ありませんが、内部リポジトリからplugin:goal形式を使用してプラグインを実行すると失敗します。例えば、目標foo-maven-pluginを提供するorg.exampleのgroupIdを持つgenerate-fooを使用できます。 mvn org.example:foo-maven-plugin:generate-fooなどのコマンドを使用してプロジェクトルートから実行しようとすると、集約モジュールでの実行に失敗します( compatibility note を参照)。

いくつかの解決策が考えられます。

  1. プラグインをMaven Centralにデプロイします(常に可能とは限りません)。
  2. すべての集約POMでリポジトリセクションを指定します(ブレーク DRY 原則)。
  3. この内部リポジトリをsettings.xmlで構成します(〜/ .m2/settings.xmlのローカル設定または/conf/settings.xmlのグローバル設定)。これらのsettings.xmlなしではビルドが失敗します(会社の外部でビルドされることを想定していない大規模な社内プロジェクトでは問題ありません)。
  4. 集約POMのリポジトリ設定で親を使用します(親POMが多すぎますか?)。
9
Ivan Dubrov