10

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

<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は、親プロジェクトには存在しませんが、子プロジェクトには存在します。

4

5 に答える 5

26

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

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

また、P2があればP1も活動しないと思います。

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

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

「プロファイルの継承」はプロジェクトの集約では機能しますが、プロジェクトの継承では機能しないため、継承という言葉に混乱しました。

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

シンプルなシナリオ

ディレクトリ構造:

simple
 \-pom.xml

ポン付け内容:

<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 には単純なシナリオのようにプロファイルがあります。ディレクトリ出力からinheritance/child/dir実行されているディレクトリの存在に関係なく:mvn help:all-profileschild

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

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

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

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

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

プロジェクト集計

ディレクトリ構造:

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

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

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

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

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

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

プロジェクトの継承

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

ノート:

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

プロジェクト集計

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

ノート:

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

結論

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

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

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

于 2013-09-19T16:04:39.010 に答える
10

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

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

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

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

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

于 2013-12-30T21:01:57.163 に答える
6

問題は継承ではなく、補間(つまり、どの値が でサポートされているか${...}) にあります: ファイルベースのプロファイルのアクティブ化は、制限された補間のみをサポートします: 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-5590のドキュメント、http: //jira.codehaus.org/browse/MNG-5608の実行時の警告より効果的な pom の結果http://jira.codehaus.org/browse/MNG-5612

于 2014-03-23T15:55:31.163 に答える
1

一般に、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 内の他のプロファイルがアクティブでない場合にのみアクティブ」を意味します。

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

于 2013-09-18T14:06:14.473 に答える