web-dev-qa-db-ja.com

Mavenで継承されたプロファイル

親のpomに次のプロファイルがあります

<profile>
    <id>P1</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
</profile>

<profile>
    <id>P2</id>
    <activation>
        <file>
            <exists>${project.basedir}/src/main/whatever</exists>
        </file>
    </activation>
</profile>

P1が子POMでアクティブであり、P2がアクティブでないのはなぜですか?

ディレクトリ${project.basedir}/src/main/whatever、親プロジェクトには存在しませんが、子プロジェクトには存在します。

9
Adrian Ber

プロファイルP2は、ディレクトリ${project.basedir}/src/main/whateverが存在していても、そのexistsタグの下のパスが既存のパスに解決されないため、アクティブ化されません。プロパティ${project.basedir}${basedir}に書き換えると、P2プロファイルがアクティブになります。

これは、${project.basedir}がプロジェクトのベースディレクトリに解決されないことを意味するはずです should 。ただし、help:effective-pomはそれが行われていることを示しています。私はこれを報告しました( MNG-5516 )。

また、P2がアクティブな場合、P1はアクティブにならないだろうと思います。

それは正しいです。 activeByDefaultのドキュメント の引用:

このプロファイル(この例ではP1)は、同じPOM内の別のプロファイルが前述の方法のいずれかを使用してアクティブ化されない限り、すべてのビルドに対して自動的にアクティブになります。デフォルトでアクティブになっているすべてのプロファイルは、コマンドラインまたはそのアクティブ化構成を介してPOMのプロファイルがアクティブ化されると、自動的に非アクティブ化されます。

「プロファイル継承」は プロジェクト集約 では機能しますが プロジェクト継承 では機能しないため、Wordinheritは私を混乱させました。

明確にするために、私はこの状況をシミュレートしました。 空のpomは、標準のモデル、グループ、アーティファクト、およびバージョンタグを除いて空であることを意味します。

単純なシナリオ

ディレクトリ構造:

simple
 \-pom.xml

pomコンテンツ:

<profiles>
    <profile>
        <id>P1</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>P2</id>
        <activation>
            <file>
                <exists>${basedir}/dir/</exists>
            </file>
        </activation>
    </profile>
</profiles>

dirディレクトリmvn help:all-profiles出力がない場合:

Profile Id: P1 (Active: true , Source: pom)
Profile Id: P2 (Active: false , Source: pom)

dirディレクトリmvn help:all-profiles出力がある場合:

Profile Id: P2 (Active: true , Source: pom)
Profile Id: P1 (Active: false , Source: pom)

プロジェクトの継承

ディレクトリ構造:

inheritance
 |--child
 |  \-pom.xml         // child pom
 \-pom.xml           // parent pom

単純なシナリオのように、子pomは空ですが、親pomにはプロファイルがあります。 childディレクトリ出力からinheritance/child/dirを実行しているmvn help:all-profilesディレクトリの存在に関係なく:

Profile Id: P1 (Active: false , Source: pom)
Profile Id: P2 (Active: false , Source: pom)

childディレクトリからmvn help:effective-pomを実行すると、プロファイルが実際に継承されていないことが示されます。 文書化 のように動作します:

マージされるPOMの要素は次のとおりです。

  • 依存関係
  • 開発者と貢献者
  • プラグインリスト(レポートを含む)
  • iDが一致するプラグインの実行
  • プラグイン構成
  • リソース

ここにはプロファイルは記載されていません。

プロジェクトの集約

ディレクトリ構造:

aggregation
 |--module
 |  \-pom.xml         // module pom
 \-pom.xml           // aggregator pom

単純なシナリオのように、モジュールpomは空ですが、アグリゲーターpomにはプロファイルがあります。 moduleディレクトリ出力からaggregation/module/dirを実行しているmvn help:all-profilesディレクトリがない場合:

Profile Id: P1 (Active: true , Source: pom)
Profile Id: P2 (Active: false , Source: pom)

moduleディレクトリ出力からaggregation/module/dirを実行しているmvn help:all-profilesディレクトリがある場合:

Profile Id: P2 (Active: true , Source: pom)
Profile Id: P1 (Active: false , Source: pom)

moduleディレクトリからmvn help:effective-pomを実行すると、プロファイルが継承されていることが示されます。これはそうではありません 明示的に文書化されています

プロジェクトの継承

複数のMavenプロジェクトがあり、それらがすべて同様の構成である場合、それらの同様の構成を引き出して親プロジェクトを作成することにより、プロジェクトをリファクタリングできます。したがって、あなたがしなければならないのは、Mavenプロジェクトにその親プロジェクトを継承させることだけであり、それらの構成はそれらすべてに適用されます。

ノート:

  • 示されているように、これはプロファイルには適用されません。
  • inheritanceディレクトリからMavenビルドを実行すると、親ビルドのみが実行されます。

プロジェクトの集約

また、一緒に構築または処理されるプロジェクトのグループがある場合は、親プロジェクトを作成し、その親プロジェクトにそれらのプロジェクトをモジュールとして宣言させることができます。そうすることで、親を作成するだけで、残りは続きます。

ノート:

  • aggregationディレクトリからMavenビルドを実行すると、各モジュールとアグリゲーターのビルドが実行されます(実際の順序は、さまざまな基準に基づいてMavenによって決定されます)。

結論

プロファイルは、グローバルに、ユーザーごとに、またはプロジェクトごとに 定義済み にすることができます。集約されたプロジェクトは(同じビルドで)一緒にビルドされるため、アクティブなプロジェクトを計算するには、何らかのプロファイル解決を実行する必要があります。したがって、これは紛らわしい部分です。

  • プロジェクトが継承される場合プロファイル親pomから子に継承されませんpom
  • プロジェクトが集約されたプロファイルの場合areアグリゲーターpomからモジュールpomに継承されます

これは、Maven3.1.0を使用してテストされました。および3.0.5。

19
linski

これを明確にするために、Mavenプロファイルは実際に継承されます。別のSO質問への参照については、以下を参照してください: Mavenプロファイルの継承 。プロジェクトでプロファイルを正常に継承しました。追加の作業は必要ありません。

元の質問に関しては、exists要素で定義された変数があります。 ドキュメント によると:

Maven 2.0.9以降、タグとは補間される可能性があります。サポートされている変数は、$ {user.home}のようなシステムプロパティと$ {env.HOME}のような環境変数です。 POM自体で定義されたプロパティと値は、ここでは補間に使用できないことに注意してください。上記の例のアクティベーターは$ {project.build.directory}を使用できませんが、パスターゲットをハードコーディングする必要があります。

だから、私がそれから得たのは、$ {project.basedir}は使用できず、機能しないということです。ただし、環境変数として定義している場合は機能します。

私が見つけた1つの注意点は、親pomで <plugin-management>を使用してプラグインを構成する必要がある です。ただし、プロファイル内では、プロファイル固有の構成を機能させるために<plugin-management>を使用してはならないことがわかりました。

10
Noremac

問題は継承ではなく補間(つまり、どの値が${...})でサポート:ファイルベースのプロファイルアクティベーションは、限定された補間のみをサポートします: http://maven.Apache.org/pom.html#Activation を参照してください。

したがって、${project.basedir}はサポートされていませんが、${basedir}(およびシステムプロパティ)のみがサポートされています。

詳細については、モデル構築アルゴリズムを参照してください。 http://maven.Apache.org/ref/3.2.1/maven-model-builder/

完全なモデル補間はプロファイルのアクティブ化後に行われます。したがって、有効なpomが${project.basedir}の補間値を示していても、プロファイルのアクティブ化が発生したときに値は計算されません。

Maven 3.2.2では、これに関して複数の機能拡張があります: http://jira.codehaus.org/browse/MNG-559 のドキュメント、 http:// jira.codehaus.org/browse/MNG-5608 そしてより効果的なpom結果 http://jira.codehaus.org/browse/MNG-5612

4
hboutemy

通常、Mavenプロファイルは継承されません(役立つ可能性のあるディスカッションとブログ投稿へのリンクについては、 http://jira.codehaus.org/browse/MNG-5127 を参照してください)。私はこのようなことをすることに成功しました:

<!-- Parent -->
<profile>
    <id>P2</id>
    <activation>
        <file>
            <exists>${project.basedir}/src/main/whatever</exists>
        </file>
    </activation>
    <!-- all the things you want to define for the child POMs -->
</profile>

<!-- Child -->
<!-- Include only the activation block, which must match parent's exactly -->
<!-- Whatever is in the parent will be inherited -->
<profile>
    <id>P2</id>
    <activation>
        <file>
            <exists>${project.basedir}/src/main/whatever</exists>
        </file>
    </activation>
</profile>

また、P2がアクティブな場合、P1はアクティブではないと思います。それの訳は <activeByDefault>はP1に当てはまります。私の意見では、要素名は少し誤解を招くものです。 「デフォルトでアクティブ」は、実際には「このPOM内の他のプロファイルがアクティブでない場合にのみアクティブ」を意味する場合、「常にアクティブ」を意味します。

上記はMaven3.0.xを使用して発見されました。

1
user944849

ファイルベースのアクティベーションがある2番目のプロファイルからP2を削除します。

<profiles>
    <profile>
        <id>P1</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>P2</id>
        <activation>
            <file>
                <exists>${basedir}/dir/</exists>
            </file>
        </activation>
    </profile>
</profiles>
0
MarkBarry