Mavenの親pomとモジュールpom


284

マルチプロジェクトのビルドで親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があります。簡潔にするために省略しました。


モジュールにもそれぞれ独自のpomがありますか?私のプロジェクトには親pomがありますが、モジュールにもそれぞれpomがあります。(おそらく、
あなたが

ええ、そうです、編集して更新します。各サブモジュールにも独自のpomがあります。
Jamie McCrindle、2010年

3
更新と同じように、2番目のオプションの利点は、サブモジュールがEclipseの個別のプロジェクトである場合、最初と3番目の例のルートpom.xmlを含めるのが難しいEclipseで管理するのが簡単であることです。
Jamie McCrindle、2010年

回答:


166

私の意見では、この質問に答えるには、プロジェクトのライフサイクルとバージョン管理の観点から考える必要があります。つまり、親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

次のように定義されています:

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

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

この「ハック」により、チェックアウト後にrootからreactorビルドを起動して、物事をさらに便利にすることができます。実際、これは私が大規模なビルドのためにMavenプロジェクトとVCSリポジトリをセットアップする方法です。それは機能するだけで、十分に拡張でき、必要なすべての柔軟性を提供します。

答えが「いいえ」の場合(最初の質問に戻ります)、パターン1を使用できる(おそらく、機能する可能性のある最も単純なことを行う)ことができます。

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

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

正直なところ、ここで一般的な答えを出さない方法がわかりません(たとえば、「物事を相互に関連付けることが理にかなっていると思うレベルを使用する」など)。とにかく、子pomは常に継承された設定をオーバーライドできます。

  • maven-releaseプラグイン、hudson、nexusは、マルチプロジェクトのセットアップ方法にどのように対処しますか(おそらく、巨大な質問です。

私が使用している設定は問題なく機能します。

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


それがどのようにスケールするかを見ることができるので、それはとても良いです。svn:externalsは、面倒であるという私の懸念に答えます。
Jamie McCrindle、2010年

@jamieお役に立ててうれしいです。
Pascal Thivent、2010年

1
「ハック」を機能させる方法について詳しく教えてください。トランクプロジェクトがあり、「reactorビルドの起動」で-​​plオプションをターゲットとすると予想されますが、このオプションはルートレベルのビルドからも渡されないため、構造でリリースを行うときに問題になります。 release-Pluginの<arguments />オプションに配置できますか?したがって、release:performはrootレベルのpomで動作しようとするため失敗します...
Jan

svn:externalsハックは、私が長い間見た中で最も有用なsvnハックです。同じリポジトリ内にプロジェクトごとのブランチがあるプロジェクトに非常に役立ちます。
omerkudat 2012年

1
こんにちはPascal。モジュールセクションで言及されているプロジェクトで、parent-pomを<parent>として使用せずにsome-other-project-parent-pomを使用する場合、バージョン番号をどのように処理しますか?そのようなプロジェクトのアーティファクトに対してどのバージョン#を取得しますか(これらのプロジェクトの<parent>セクションにあるアーティファクトのバージョン#またはこれらのプロジェクトをモジュールとしてリストするプロジェクトのバージョン#)?stackoverflow.com/questions/25918593/...
AKS

34

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

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

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

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

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

その目的は、大規模なビルドにスケーラブルであることであり、多数のプロジェクトとアーティファクトにスケーラブルでなければなりません。

マルチプロジェクトにはツリー構造があるため、親pomの1つのレベルに移動する必要はありません。ニーズに適したプロジェクト構造を見つけるようにしてください-典型的な例は、マルチモジュールプロジェクトを不自然にする方法です

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

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

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

この構成は、「会社」の親pomとプロジェクトの親pomに賢く分割する必要があります。すべてのプロジェクトに関連するものは「会社」の親に移動し、現在のプロジェクトに関連するものはプロジェクトの親に移動します。

  • maven-releaseプラグイン、hudson、nexusは、マルチプロジェクトのセットアップ方法にどのように対処しますか(おそらく、巨大な質問です。

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


1
つまり、親プロジェクト/ pomには2つのタイプがあります。<modules>宣言のないもの。これは継承に使用されるものです。そして、<multimodule>宣言を持つ親プロジェクト。これはサブモジュールが継承しないもので、ホールドプロジェクトのビルドを管理するためだけのものです。私は正しいですか?
lisak

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

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

  3. 一般的なパターン(現時点では#1を無視します)は、projects-with-codeで親プロジェクトを親として使用し、最上位を親として使用するようにします。これにより、コアなものをすべての人が共有できますが、#2で説明されている問題は回避されます。

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

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


2
私はイビリオを見てきましたが、多くのプロジェクトが「独立した」親のpomを好むようです。Hibernate、ActiveMQ、Jetty、XStreamなど。これが事実上のメカニズムであることを示唆しています。
Jamie McCrindle、2010年

2
独立した親のもう1つの欠点は、Mavenリリースプラグインが、リリースを実行する前に親をバージョンに固定する必要があるように見えることです。親はあまり変更すべきではないので、おそらくそれほど問題にはなりません。
Jamie McCrindle、2010年

9

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

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

いくつかの解決策が可能です:

  1. プラグインをMaven Centralにデプロイします(常に可能とは限りません)。
  2. すべての集約POMでリポジトリセクションを指定します(DRYの原則に違反)。
  3. この内部リポジトリーを、settings.xml(〜/ .m2 / settings.xmlのローカル設定または/conf/settings.xmlのグローバル設定)で構成します。これらのsettings.xmlがないとビルドが失敗します(社外でのビルドが想定されていない大規模な社内プロジェクトの場合は問題ありません)。
  4. 集約POMでリポジトリ設定の親を使用します(親POMが多すぎる可能性がありますか?)。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.