4

Mavenに関する実行可能性に関する質問です。特に、集約pomでプロパティを定義し、それらを参照されるモジュールに挿入して、そのモジュールが継承階層で定義されたデフォルトのプロパティをローカルで上書きできるかどうかについて。

詳細に興味がある場合は、セットアップについて説明します。ただし、その前に、プロジェクトの構造についてチームとして幅広く話し合い、ニーズに非常によく適合していることをお伝えしておきます。現時点では、他の構造に関する提案を探しているわけではありませんが、Mavenが私たちのニーズを満たすことができるかどうかだけを調査しています。

だから、私たちのセットアップ。私はそれを本質に要約します。AとBの2つのソースプロジェクトがあります。これらはそれぞれ、実際にはそれぞれParentAとParentBの子モジュールです。ParentAとParentBには技術的には多数の子モジュールがありますが、この例では、簡単にするためにそれぞれを明示的に参照します。ここまでは順調ですね。ParentAはAをサブモジュールとして参照し、AはParentAをその親として参照します。同じ関係がBとParentBにも当てはまります。

今、楽しみが来ます。ParentAとParentBの両方のスーパー親pomが、dependencyManagementやプラグインなどの共有プロパティと構成を継承するようにします。ただし、このスーパー親pomがビルドを担当することは望ましくありません。代わりに、さまざまなモジュールを選択的にビルドするいくつかのビルドプロジェクトを定義したいと思います。この例では、BuildABとBuildBを紹介します。最初のビルドはA、次にBをビルドしますが、2番目のビルドはBだけです。実際には、これらのインターリーブモジュールグループと依存関係がかなりあります。最後に、全体像を完成させるために、BからAへの依存関係があります。

アスキーアートを使ってこれを描いてみましょう;)

継承

A --> ParentA --> parent
B --> ParentB --> parent

サブモジュールの関係

BuildAB ==> { (ParentA ==> A) (ParentB ==> B) }
BuildB ==> (ParentB ==> B)

依存関係

B > A

現在、BuildABファイルとBuildBファイルのプロパティを使用して依存関係を定義することは不可能です。これらのビルドファイルは継承ツリーの一部ではないため、プロパティを取得するものはありません。ただし、BuildABとBuildBを実行する場合は、依存関係のバージョンを異なる方法で制御する必要があります。依存関係をスーパーペアレントに配置するだけでは、要件に合わせて依存関係を削減することはできません。

なぜこれが考えられるのか疑問に思っている場合は、1つのチームがBモジュールを開発しており、Aにも小さな変更を加えている可能性があります。他の開発者は、依存関係のおかげでBに影響を与えるプロジェクトAの最新かつ最高のものに取り組んでいる可能性があります。Mercurialのおかげで、これをソースコードで処理するための優れたメカニズムがあります。しかし、Mavenでこれを機能させるのに本当に苦労しています。

理想的には、各ビルドファイルは、最初に親から継承するサブモジュールに依存します。ただし、この継承をオーバーライドする必要がある場合は、ビルドファイルで注入可能なプロパティを指定できるようにします。これは、モジュールで最初に指定された場合とまったく同じように機能します。もちろん、ソース制御されているpomを実際に変更することなくすべて。

評価したいのは、プラグインまたはパッチを介して、これを行うためにMavenを変更する余地があるかどうかです。

私たちはこれまでプラグインを書いたことがありません(そして率直に言って、これに関するチュートリアルやオンラインのものは乏しく、実際には開発者に優しいものではありません-誰かが私が見逃した良いチュートリアルを持っていない限り:))それは実行可能のようです。

だから基本的に、

  • 以前に同様の要件を自分で処理し、既存のプラグインで機能させたことはありますか?
  • 私たちが見逃している簡単なトリックはありますか?
  • 同様のプラグインを作成し、開始する場所を推奨できますか?
  • そのようなプラグインが機能しない可能性がある実際的な理由を知っていますか?
  • Mavenのソースコードに取り組んでいて、結果のコードを提供できるかどうかを知っていますか...そして、必要に応じてどこから始めればよいのでしょうか。

最後のコメント。私たちはEclipseで開発しているので、プロパティを挿入せずに動作するビルドも必要です。これは通常の継承ツリーを介して行われると思います。

どうもありがとうございました。少し難しい質問だと思います。

4

1 に答える 1

2

あらゆる種類の特別な魔法の場合: maven build extension を使用します。

これはあまり知られていない (そして maven にとってはいつものように、ため息をつく) 十分に文書化されていないメカニズムですが、私が見る限り、ビルドプロセス全体に影響を与える公式に承認された方法です。

import org.apache.maven.AbstractMavenLifecycleParticipant;
import org.apache.maven.execution.MavenSession;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;

@Component(role = AbstractMavenLifecycleParticipant.class, hint = "mySpecialService")
public class MySpecialExtension
    extends AbstractMavenLifecycleParticipant
{

    @Requirement
    private Logger logger;

    @Override
    public void afterProjectsRead( MavenSession session ) {
        // ...do you magic here

        // for example, to set some POM properties
        Properties sysProps = session.getSystemProperties();
        ....
        Properties projProps = session.getCurrentProject().getProperties();
        projProps.setProperty("..",val);

この関数は、pom.xml ファイルを解析し、基本的な POM をメモリ内に構築した直後に呼び出されますが、それ以降の構築アクティビティが開始される前に呼び出されます。マルチモジュール プロジェクトでは、一部のサブモジュールでのみ定義されている場合でも、拡張機能はルート プロジェクトから呼び出されます。この時点で、理論的には、いくつかのプロパティを pom に注入する、アーティファクト マネージャーからさらにプロジェクトをロードしてビルド リアクターに追加する、特定のプラグインを検索する、POM を再形成するなど、ビルド プロセスで何でもできます一部のモジュール、またはどこにも宣言されていないものを構築することさえできます (!)

このような拡張機能を構築するには、コードを別の Maven プロジェクトに配置します。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <prerequisites>
        <maven>3.0</maven>
    </prerequisites>

    <name>my-special-service</name>
    <groupId>my.group</groupId>
    <artifactId>my-special-service</artifactId>
    <packaging>jar</packaging>

    <parent>
       ....
    </parent>

    <properties>
        <mavenApiVer>3.0.5</mavenApiVer>
        <mavenModelVer>2.2.1</mavenModelVer>
    </properties>

<build>
    <plugins>
        <!-- Maven Build Extension -->
        <plugin>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-component-metadata</artifactId>
            <version>1.5.5</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate-metadata</goal>
                        <!-- goal>generate-test-metadata</goal -->
                    </goals>
                </execution>
            </executions>
            </plugin>
            <!-- Maven Build Extension -->
        </plugins>
    </build>


    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-project</artifactId>
            <version>${mavenModelVer}</version>
        </dependency>

        <!-- Maven Build Extension -->
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-compat</artifactId>
            <version>${mavenApiVer}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-core</artifactId>
            <version>${mavenApiVer}</version>
        </dependency>
        <!-- Maven Build Extension -->

        ....

    </dependencies>
</project>

拡張機能を他のプロジェクトで使用するには、次を追加するだけです

<build>
    <extensions>
        <extension><!-- Maven Build Extension: my Special Service -->
            <groupId>my.group</groupId>
            <artifactId>my-special-service</artifactId>
            <version>.....</version>
        </extension>
    </extensions>

    <pluginManagement>
    ....

特定のユースケースでは、構成管理システムから透過的に取得する必要があるいくつかの一般的なサービス (特に、ビルド プロセスで特定のプラグインから使用されるデータベース URL) がありました。プロパティ ファイルをすべての開発者とすべてのビルド サーバーにロールアウトすることは、環境が異機種に近いため現実的ではありません。

于 2013-05-08T13:57:29.710 に答える