web-dev-qa-db-ja.com

MavenのPOMファイルからプロパティファイルを読み取る

なぜこれが機能しないのですか?プロパティファイルからバージョン番号を取得する方法。

Pom.xmlのプロパティの読み取り

<project>
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>properties-maven-plugin</artifactId>
        <version>1.0</version>
        <executions>
          <execution>
            <phase>initialize</phase>
            <goals>
              <goal>read-project-properties</goal>
            </goals>
          </execution>
          <configuration>
            <files>
              <file>dev.properties</file>
            </files>
          </configuration>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Dev.properties内

org.aspectj.aspectjrt.version = 1.6.11

Pom.xmlの依存関係

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj.aspectjrt.version}</version>
        </dependency>

エラー:依存関係は有効なバージョンである必要があります

21
Debajyoti Das

コマンドラインからMavenを起動すると、いくつかの段階を経ます。これらの段階の疑似説明を以下に示します。私が意図している正確な順序付けを意図的に簡略化しているため(やや不正確/順序が間違っていることを言うリスクがあるため)、実行しようとしていることが機能しない理由を確認できます。

  1. 最初にコマンドラインを解析し、-Dname=valueを使用してコマンドラインで定義されたプロパティをMavenSessionに注入します

  2. コマンドラインオプションを定義するリアクターがチェックされ、ビルドするプロジェクトのリスト(リアクターとも呼ばれます)を決定します。 -Nは、ルートのみをビルドすることを意味しますpom.xml-plは、ビルドするモジュールのリストを指定でき、-amおよび-AMDは、-plで指定されたモジュールからそれぞれ上流または下流のモジュールを追加できます。 Mavenはこの時点でpom.xmlファイルを解析していません。

  3. -Pプロファイルのアクティブ化ルールは、アクティブ化するプロファイルを確認するために解析されます。

  4. これで、Mavenはpom.xmlファイルの解析を開始するのに十分な知識を獲得しました。まず、ルートpom.xml、つまり現在のディレクトリにあるルート(またはpom.xmlで代替-fを指定した場合は、それを指定)をロードして解析します。この最初の解析は、ビルドするプロジェクトのリストを理解することに集中しています。プロファイルのアクティブ化は、利用可能な<modules>のリストに影響を与える可能性があるため、でのみ考慮されます。 pom.xmlのプロパティの解析は現時点では行われていないため、pom.xmlのグループID、アーティファクトID、バージョン、およびパッケージの座標にプロパティを含めることはできません。 (注意深い読者は、この段階ではシステムプロパティのみが解析されているため、pom.xml内のプロパティに基づいてプロファイルをアクティブ化できない理由も説明していることがわかります。)

  5. プロジェクトのセットが検証されると、Mavenはこれらのpom.xmlファイルをさらに解析して、ビルド拡張のリスト(存在する場合)とプラグインのリストを作成します。この段階では、解析には各プロジェクトの<properties>の評価が必要です。そのため、これらは評価されて効果的なモデルに「注入」されます。したがって、システムプロパティとpomプロパティを使用して、(xpath)/project/build/extensions/project/build/pluginManagement/plugins/plugin/project/build/pluginManagement/plugins/plugin/dependencies/project/build/plugins/pluginおよび/project/build/plugins/plugin/dependencies内の座標と追加の依存関係を定義できます。

  6. これで、Mavenはコマンドラインで指定された目標とフェーズのリストの解析を開始します。部分的に指定された目標は、プラグインのリストとの一致について評価されます。一致は、プラグインの目標が実行されるすべてのプロジェクトに対して一意である必要があります(つまり、アグリゲーターの目標の場合、一致はルートでのみ必要ですが、他のすべての「通常の」目標の場合、プラグインの短い名前はすべてのプロジェクトで同じプラグイン)。ライフサイクルフェーズは、デフォルトのライフサイクルの1つ、またはビルド拡張で定義されたライフサイクルからのものである必要があります。

  7. パースされた目標とフェーズのリストから、Mavenはビルドプランを構築します。つまり、どのプロジェクトでどのような順序で実行するかなどです。これを行うために、Mavenはreactorプロジェクトのpom.xmlファイルで定義されたプロジェクト依存関係のリストを解析する必要があります。これは、リアクタ内の別のプロジェクトによって依存関係が生成され、それによってプロジェクト実行のシーケンスが強制されるためです。したがって、システムプロパティとpomプロパティを使用して(xpath)/project/dependencyManagement/dependencies/dependency/project/dependencies/dependency内の座標と追加の依存関係を定義できますが、現時点ではプラグインが実行されていないことに注意してください。

  8. Mavenにビルドプランが用意されたので、Mavenは、ビルドされた順にそのプランに従います。 CLIの最初の目標/フェーズが目標だった場合、その目標が呼び出されます。最初の目標/フェーズがデフォルトのビルドライフサイクルのフェーズである場合、Mavenはinitializeフェーズから開始し、そのフェーズにバインドされたすべてのプラグインを実行します...フェーズのリストに沿って同様の方法で続行しますそしてプロジェクトのリスト。 initializeフェーズは、デフォルトのビルドライフサイクルの一部としてのみ実行されることにも注意してください。デフォルトのクリーンまたはデフォルトのサイトライフサイクルでは実行されず、カスタムライフサイクルでは実行されません。 (注意深い読者は、これが質問が試みているテクニックの別の問題を浮き彫りにしていると結論します)。注:アグリゲーターの目標はリアクターで「ブレーク」を形成することに注意してください。したがって、Mavenにclean package foo:bar siteを実行するように依頼すると、foo:barはアグリゲーターのモジョ目標であり、リアクター内のすべてのプロジェクトに対してclean packageが実行され、foo:barが実行されます。ルートに対して実行すると、リアクタ内のすべてのプロジェクトに対してsiteが実行されます。言い換えると、ビルドプランは、非アグリゲーターの目標とフェーズの最も長い連続実行を、アグリゲーターの目標の最も長い連続実行で分割したものになります。

  9. 各モジョ(つまり、フェーズにバインドされた、またはコマンドラインから直接指定された目標)を呼び出す前に、Mavenはそのモジョの有効なpom.xmlに対して<configuration>を評価します。この時点で、Mavenはシステムプロパティ、pom およびで指定されたプロパティを利用できます。以前に実行されたmojoによってMavenSessionに注入されたプロパティ。したがって、<configuration>はこれらのプロパティのいずれかを参照できます...

    さておき

    ここで注意点があります... set(xpath)/project/build/directory to ${some-property-i-will-set-via-a-mojo}を参照し、それを<configuration>から参照すると、悲しいことに、(xpath)/project/build/directoryが効果的なpom.xmlに評価されているということです before 任意のプラグインの実行、つまり${project.build.directory}には、_MavenProject内の${some-property-i-will-set-via-a-mojo}タイプのリテラル値Java.io.Fileおよびが与えられるため、実際には発生したのはnew File(project.getBaseDir(),"${some-property-i-will-set-via-a-mojo}")です。挿入する<configuration>フィールドのタイプがFileの場合、タイプ変換は必要ないため、値はそのまま挿入され、プロパティの置換は行われません。

    上記で概説したような他のEdgeケースもありますが、一般的にプロパティの置換は、「mojo注入」プロパティ( MojoのプロパティMavenプラグインによって提供されるプロパティ)で機能します<configuration>セクション内。これらのセクション以外では機能しません。

そこで、さまざまなプロパティタイプについて、Stephenの簡単な経験則を示します。

システムのプロパティ

これらはどこでも機能しますが、極端に/project/(parent/)?/(groupId|artifactId|version|packaging)では危険です。これは、プロジェクトがプルされたときに定義されるシステムプロパティについてこれまで何も制御できないためです。推移的な依存関係として。 /project/(parent/)?/(groupId|artifactId|version|packaging)内の${...}拡張の使用は、エアバッグの代わりにハンドルから突き出た30cm(12インチ)の金属スパイクで車を時速200キロで運転することと同等と見なされるべきです...ああ、シートベルトなし...そして、あなたはたった10ユニットのアルコールと2ラインのコカインを手に入れました。

pom.xmlプロパティ(およびsettings.xmlプロパティ)

これらはほとんどの場所で機能しますが、/project/(parent/)?/(groupId|artifactId|version|packaging)内では使用できず(これらのフィールドが評価されているときに解析されていないため)、アクティブなプロファイルの検討には使用できません(ここでも解析されていないため)プロファイルのアクティブ化が評価されているとき)

Mojo注入プロパティ

これらは<configuration>セクション内で機能し、間接的に使用すると(注入されたMojo Stringパラメータの再帰的補間により)機能する可能性がありますが、不確実性が伴うため、プラグインとレポートの<configuration>セクションへの使用を制限することをお勧めしますのみ。

最後に

プロジェクトが依存関係としてリストされている場合にどうなるかを考えてください。 mojoを使用して依存関係を指定し、ディスク上の.propertiesファイルから依存関係をプルした場合、依存関係がMavenリポジトリーからプルされたときに、Mavenはそれを複製する方法がありません。したがって、Mavenは依存関係を判別できません。従ってそれは決して働くことができませんでした。

あなたができることは、外部システム(例えばANT)を使用して、バージョンからそのファイルに置き換えられたテンプレートからpom.xmlを生成することです。次に、インスタンス化されたテンプレートを使用してビルドします。

89