1. 概要

Maven Polyglot は、POMモデルを任意の言語で記述できるようにするMavenコア拡張機能のセットです。 これには、XML以外の多くのスクリプトとマークアップ言語が含まれます。

Mavenポリグロットの主な目標は、XMLが今日ではもはや頼りになる言語ではなくなったため、XMLから脱出することです。

このチュートリアルでは、最初にMavenコア拡張の概念とMavenPolyglotプロジェクトを理解することから始めます。

次に、有名なpom.xml。ではなくJSONファイルからPOMモデルを構築できるようにするMavenコア拡張機能を作成する方法を示します。

2. Mavenコア拡張ロードメカニズム

Mavenコア拡張機能は、Maven初期化で、Mavenプロジェクトのビルド開始前にロードされるプラグインです。 これらのプラグインを使用すると、コアを変更せずにMavenの動作を変更できます。

たとえば、起動時にロードされたプラグインは、Mavenのデフォルトの動作をオーバーライドし、pom.xml以外のファイルからPOMモデルを読み取ることができます。

技術的には、 Mavenコア拡張はextensions.xmlファイルで宣言されたMavenアーティファクトです:

${projectDirectory}/.mvn/extensions.xml

拡張機能の例を次に示します。

<?xml version="1.0" encoding="UTF-8"?>
<extensions>
    <extension>
        <groupId>com.baeldung.maven.polyglot</groupId>
        <artifactId>maven-polyglot-json-extension</artifactId>
        <version>1.0-SNAPSHOT</version>
    </extension>
</extensions>

最後に、このメカニズムにはMaven3.3.1以降が必要であることに注意する必要があります。

3. Mavenポリグロット

Maven Polyglotは、コア拡張機能のコレクションです。これらはそれぞれ、スクリプトまたはマークアップ言語からPOMモデルを読み取る役割を果たします。

Maven Polyglotは、次の言語の拡張機能を提供します。

+-----------+-------------------+--------------------------------------+
| Language  | Artifact Id       | Accepted POM files                   |
+-----------+-------------------+--------------------------------------+
| Atom      | polyglot-atom     | pom.atom                             |
| Clojure   | polyglot-clojure  | pom.clj                              |
| Groovy    | polyglot-groovy   | pom.groovy, pom.gy                   |
| Java      | polyglot-java     | pom.java                             |
| Kotlin    | polyglot-kotlin   | pom.kts                              |
| Ruby      | polyglot-ruby     | pom.rb, Mavenfile, Jarfile, Gemfile  |
| Scala     | polyglot-scala    | pom.scala                            |
| XML       | polyglot-xml      | pom.xml                            |
| YAML      | polyglot-yaml     | pom.yaml, pom.yml                    |
+-----------+-------------------+--------------------------------------+

次のセクションでは、最初に、上記でサポートされている言語の1つを使用してMavenプロジェクトを構築する方法について説明します。

次に、JSONベースのPOMをサポートする拡張機能を記述します。

4. Mavenポリグロット拡張機能の使用

XMLとは異なる言語に基づいてMavenプロジェクトを構築する1つのオプションは、Polyglotプロジェクトによって提供されるアーティファクトの1つを使用することです。

この例では、pom.yaml構成ファイルを使用してMavenプロジェクトを作成します。

最初のステップは、Mavenコア拡張ファイルを作成することです。

${projectDirectory}/.mvn/extensions.xml

次に、次のコンテンツを追加します。

<?xml version="1.0" encoding="UTF-8"?>
<extensions>
    <extension>
        <groupId>io.takari.polyglot</groupId>
        <artifactId>polyglot-yaml</artifactId>
        <version>0.3.1</version>
    </extension>
</extensions>

上記の言語に応じてartifactIdを選択した言語に自由に調整し、新しいバージョンが利用可能かどうかを確認してください。

最後のステップは、YAMLファイルでプロジェクトメタデータを提供することです。

modelVersion: 4.0.0
groupId: com.baeldung.maven.polyglot
artifactId: maven-polyglot-yml-app
version: 1.0-SNAPSHOT
name: 'YAML Demo'

properties: {maven.compiler.source: 1.8, maven.compiler.target: 1.8}

これで、通常どおりにビルドを実行できます。 たとえば、次のコマンドを呼び出すことができます。

mvn clean install

5. PolyglotTranslateプラグインの使用

サポートされている言語の1つに基づいてプロジェクトを取得する別のオプションは、polyglot-translate-pluginを使用することです。

これは、従来のpom.xml。を使用して既存のMavenプロジェクトから開始できることを意味します。

次に、 translateプラグインを使用して、既存のpom.xmlプロジェクトを目的のポリグロットに変換できます。

mvn io.takari.polyglot:polyglot-translate-plugin:translate -Dinput=pom.xml -Doutput=pom.yml

6. カスタム拡張機能の作成

JSONはMavenPolyglotプロジェクトによって提供される言語の1つではないため、JSONファイルからプロジェクトメタデータを読み取ることができる単純な拡張機能を実装します

私たちの拡張機能は、Mavenのデフォルト実装をオーバーライドするMaven ModelProcessorAPIのカスタム実装を提供します。

これを実現するために、POMファイルを見つける方法と、メタデータを読み取ってMaven ModelAPIに変換する方法の動作を変更します。

6.1. Mavenの依存関係

まず、次の依存関係を持つMavenプロジェクトを作成します。

<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-core</artifactId>
    <version>3.5.4</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
</dependency>

ここではコア拡張機能を実装するため、maven-core依存関係を使用します。 Jackson 依存関係は、JSONファイルを逆シリアル化するために使用されます。

また、MavenはPlexus依存性注入コンテナを使用するため、実装はPlexusコンポーネントである必要があります。 したがって、Plexusメタデータを生成するには、このプラグインが必要です。

<plugin>
    <groupId>org.codehaus.plexus</groupId>
    <artifactId>plexus-component-metadata</artifactId>
    <version>1.7.1</version>
    <executions>
        <execution>
            <goals>
                <goal>generate-metadata</goal>
            </goals>
        </execution>
    </executions>
</plugin>

6.2. カスタムModelProcessorの実装

Mavenは、 ModelBuilder.build()メソッドを呼び出してPOMモデルを構築し、 ModelProcessor.read()メソッドに委任します。

Mavenは、 DefaultModelProcessor 実装を提供します。これは、デフォルトで、ルートディレクトリにあるかパラメータコマンドとして指定されたpom.xmlファイルからPOMモデルを読み取ります。

その結果、デフォルトの動作をオーバーライドするカスタムModelProcessor実装を提供します。 これが、POMモデルファイルの場所とその読み取り方法です。

それでは、 CustomModelProcessor 実装を作成し、それをPlexusコンポーネントとしてマークすることから始めましょう。

@Component(role = ModelProcessor.class)
public class CustomModelProcessor implements ModelProcessor {

    @Override
    public File locatePom(File projectDirectory) {
        return null;
    }

    @Override
    public Model read(
      InputStream input, 
      Map<String, ?> options) throws IOException, ModelParseException {
        return null;
    }
    //...
}

@Componentアノテーションは、実装をDIコンテナー(Plexus)によるインジェクションに使用できるようにします。したがって、Mavenが ModelBuilder、ModelProcessorインジェクションを必要とする場合Plexusコンテナーは、DefaultModelProcessor。ではなくこの実装を提供します

次に、 LocatePom()メソッドの実装を提供します。 このメソッドは、Mavenがプロジェクトのメタデータを読み取るファイルを返します。

したがって、 pom.json ファイルが存在する場合はそれを返します。存在しない場合は、通常どおりpom.xmlを返します。

@Override
public File locatePom(File projectDirectory) {
    File pomFile = new File(projectDirectory, "pom.json");
    if (!pomFile.exists()) {
        pomFile = new File(projectDirectory, "pom.xml");
    }
    return pomFile;
}

次のステップは、このファイルを読み取り、Mavenモデルに変換することです。 これは、read()メソッドによって実現されます。

@Requirement
private ModelReader modelReader;

@Override
public Model read(InputStream input, Map<String, ?> options) 
  throws IOException, ModelParseException {
 
    FileModelSource source = getFileFromOptions(options);
    try (InputStream is = input) {
        //JSON FILE ==> Jackson
        if (isJsonFile(source)) {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(input, Model.class);
        } else {
            // XML FILE ==> DefaultModelReader
            return modelReader.read(input, options);
        }
    }
    return model;
}

この例では、ファイルがJSONファイルであるかどうかを確認し、Jacksonを使用してMaven Modelに逆シリアル化します。それ以外の場合は、通常のXMLファイルであり、Mavenによって読み取られます。 ]DefaultModelReader。

拡張機能をビルドする必要があります。これで使用できるようになります。

mvn clean install

6.3. 拡張機能の使用

拡張機能の使用法を示すために、Spring BootWebプロジェクトを使用します。

まず、Mavenプロジェクトを作成し、pom.xml。を削除します。

次に、上記で実装した拡張機能を${projectDirectory}/。mvn/extensions.xml:に追加します。

<?xml version="1.0" encoding="UTF-8"?>
<extensions>
    <extension>
        <groupId>com.baeldung.maven.polyglot</groupId>
        <artifactId>maven-polyglot-json-extension</artifactId>
        <version>1.0-SNAPSHOT</version>
    </extension>
</extensions>

そして最後に、次のコンテンツでpom.jsonを作成します。

{
  "modelVersion": "4.0.0",
  "groupId": "com.baeldung.maven.polyglot",
  "artifactId": "maven-polyglot-json-app",
  "version": "1.0.1",
  "name": "Json Maven Polyglot",
  "parent": {
    "groupId": "org.springframework.boot",
    "artifactId": "spring-boot-starter-parent",
    "version": "2.0.5.RELEASE",
    "relativePath": null
  },
  "properties": {
    "project.build.sourceEncoding": "UTF-8",
    "project.reporting.outputEncoding": "UTF-8",
    "maven.compiler.source": "1.8",
    "maven.compiler.target": "1.8",
    "java.version": "1.8"
  },
  "dependencies": [
    {
      "groupId": "org.springframework.boot",
      "artifactId": "spring-boot-starter-web"
    }
  ],
  "build": {
    "plugins": [
      {
        "groupId": "org.springframework.boot",
        "artifactId": "spring-boot-maven-plugin"
      }
    ]
  }
}

これで、次のコマンドを使用してプロジェクトを実行できます。

mvn spring-boot:run

7. 結論

この記事では、MavenPolyglotプロジェクトを使用してデフォルトのMavenの動作を変更する方法を示しました。 この目標を達成するために、コアコンポーネントのロードを簡素化する新しいMaven3.3.1機能を使用しました。

コードとすべてのサンプルは、通常どおりGithubにあります。