web-dev-qa-db-ja.com

Maven-プロパティに基づいて子プロファイルをアクティブ化します

シナリオ:

  1. ギヴン
    1. プロファイルと子(モジュールとして)を定義する親POM
    2. 親POMを参照してプロファイルを使用する子プロジェクト。
  2. 親でのプロファイルの実行をスキップし、子でのみ実行することを目的としています
  3. プロファイルにはアクティベーションセクションがあります<activation><property><name>foo</name></property><activation>
  4. 親がfooプロパティを定義していないため、プロファイルは非アクティブであり、親ビルドに対して実行されません
  5. ここで、子ビルドが実行されてプロファイルがアクティブ化されたときにプロパティが取得されることを期待して、子に<properties><foo>true</foo></properties>を定義しています。そのような運はありません。プロファイルがアクティブ化されることはありません。これは、プロパティが設定されないことを示しています。
  6. 注意:mvn package -Dfoo=trueは、親と子の両方でプロファイルをアクティブにします

私は不可能なことをしようとしているのですか、それとも単に間違っているのですか?

P.S.うーん-親でプロパティを定義しても、プロファイルはトリガーされません。何が得られますか?

24
Bostone

@ rich-sellerの回答と@Bostoneの自己回答を拡張するために、親POMがいくつかのプロファイルを代替として定義し、子POMがデフォルトでこれらのプロファイルの1つを選択する設定を行うことは不可能のようですが、子の選択を一時的に(つまりCLIで)オーバーライドします。フレームワークと関連するプラグインを使用するプロジェクトの親POMについて考えてみます。どちらのバージョンも、プロパティによって定義されていると想定できます。

<profiles>
  <profile>
    <id>newest</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <framework.version>2.0</framework.version>
      <plugin.version>2.0</plugin.version>
    </properties>
  </profile>
  <profile>
    <id>older</id>
    <activation>
      <property>
        <name>older.framework</name>
        <value>true</value>
      </property>
    </activation>
    <properties>
      <framework.version>1.1</framework.version>
      <plugin.version>1.1</plugin.version>
    </properties>
  </profile>
</profiles>

これで、この親POMから継承する子は、デフォルトで2.0を使用するようになり、-Polderまたは-Dolder.framework=trueは、古いフレームワークでビルドを試みるために機能します(互換性のテストなど)。ただし、子POMに書き込むことはできません

<properties>
  <older.framework>true</older.framework>
</properties>

olderプロファイルを自動的にアクティブにします。 newestがデフォルトでアクティブでない場合は、ファイルベースのアクティベーションを使用してこのモジュールを1.1に対してビルドできますが、2.0に対して一時的に実行するのは簡単ではありません。両方のolderおよびnewestプロファイルは、-Pnewestを渡した場合にアクティブになるため、他のプロファイルを明示的に無効にする必要があります。あなたがそれらのダースを持っている場合は不合理です。したがって、プロファイル情報を子POMにコピーする以外に解決策はありません。

<properties>
  <framework.version>1.1</framework.version>
  <plugin.version>1.1</plugin.version>
</properties>

この時点で、-Pnewestnotでこれらのプロパティをオーバーライドするように機能しないため、-Dframework.version=2.0 -Dplugin.version=2.0を使用する必要があります。

つまり、プロファイルは、すべての子モジュールがデフォルトで同じプロファイル(ここではnewest)を使用できる場合にのみ役立ちます。それらのいくつかが通常1.1で構築され、いくつかが2.0で構築されている場合、プロファイルは役に立ちません。

これは、Mavenコア拡張、またはおそらくMaven3ビルド拡張のユースケースのようです。 http://docs.codehaus.org/display/MAVEN/Custom+Profile+Activators および https://github.com/maoo/maven-tiles 頭に浮かぶ。

9
Jesse Glick

私自身の質問に直接答えるには:マルチモジュールビルドでは、ビルドが実行される前にすべてのプロパティが設定されるため、いずれかのプロファイルをアクティブ化/非アクティブ化することは不可能ですモジュールduringは、子POMでプロパティを設定することに基づいてビルドします。ただし、他の方法を使用してそれを行う方法を探している場合は、 このコメントを読んでください

7
Bostone

プロファイルは、コマンドラインから渡されたプロパティによってのみアクティブ化できます。これは、POMのプロパティは、POMが解析された後でのみ処理できるためです。この時点では、プロファイルのアクティブ化を解決するには遅すぎます。

コマンドラインからプロパティを渡すか、settings.xmlでプロファイルのアクティブ化を指定するか(通常は良いアイデアではありません)、または私の-の回避策を使用できない限り、このアプローチでは少しキャッチ22になります。 前の回答 マーカーファイルの存在を使用します。

Maven 2.1.0+を使用している場合の最後の代替手段の1つは、親POMのコマンドラインからのみプロファイルを非アクティブ化することです。これは明らかにまだです理想的ではありません。

「!」のいずれかの文字を使用してプロファイルを非アクティブ化できます。またはこのような「-」:

mvn install -P !profile-1,!profile-2
5
Rich Seller