Mavenポリグロット

メイベンポリグロット

1. 概要

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

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

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

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

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

The Maven core extensions are plugins loaded at Maven initializationおよびMavenプロジェクトのビルド開始前。 これらのプラグインにより、コアを変更せずにMavenの動作を「変更」できます。

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

技術的には、a Maven core extension is a Maven artifact declared in an extensions.xml file:

${projectDirectory}/.mvn/extensions.xml

拡張機能の例は次のとおりです。



    
        com.example.maven.polyglot
        maven-polyglot-json-extension
        1.0-SNAPSHOT
    

最後に、this mechanism requires Maven 3.3.1 or higherに注意する必要があります。

3. メイベンポリグロット

Maven Polyglot is a collection of core extensions.これらはそれぞれ、スクリプトまたはマークアップ言語から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つを使用することです。

この例では、we’ll create a Maven project with a pom.yaml configuration fileです。

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

${projectDirectory}/.mvn/extensions.xml

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



    
        io.takari.polyglot
        polyglot-yaml
        0.3.1
    

上記の言語に応じて、選択した言語に合わせてartifactIdを自由に調整し、new versionが使用可能かどうかを確認してください。

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

modelVersion: 4.0.0
groupId: com.example.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プロジェクトから開始できることを意味します

次に、we can convert the existing pom.xml project to the desired polyglot by using the translate plugin

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

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

JSONはMavenPolyglotプロジェクトによって提供される言語の1つではないため、we’ll implement a simple extension that allows reading project metadata from a JSON file

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

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

6.1. Mavenの依存関係

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


    org.apache.maven
    maven-core
    3.5.4
    provided


    com.fasterxml.jackson.core
    jackson-databind
    2.9.6

ここではwe use the maven-core dependency as we’ll implement a core extensionです。 Jackson依存関係は、JSONファイルを逆シリアル化するために使用されます。

また、MavenはPlexus Dependency Injectionコンテナー、we need our implementation to be a Plexus componentを使用します。 したがって、Plexusメタデータを生成するには、このプラグインが必要です。


    org.codehaus.plexus
    plexus-component-metadata
    1.7.1
    
        
            
                generate-metadata
            
        
    

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 options) throws IOException, ModelParseException {
        return null;
    }
    //...
}

The @Component annotation will make the implementation available for injection by the DI container (Plexus).したがって、MavenがModelBuilder,ModelProcessorインジェクションを必要とする場合、PlexusコンテナはDefaultModelProcessor.ではなくこの実装を提供します

次に、we’ll provide the implementation for the locatePom() method。 このメソッドは、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 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を使用してMavenModel.に逆シリアル化します。それ以外の場合は通常のXMLファイルであり、MavenDefaultModelReader.によって読み取られます。

拡張機能を構築する必要があり、使用できる状態になります。

mvn clean install

6.3. 拡張機能を使用する

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

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

次に、we’ll add the extension that we have implemented above, in ${projectDirectory}/.mvn/extensions.xml:



    
        com.example.maven.polyglot
        maven-polyglot-json-extension
        1.0-SNAPSHOT
    

そして最後に、次の内容でpom.jsonを作成します。

{
  "modelVersion": "4.0.0",
  "groupId": "com.example.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動作を変更する方法を示しました。 この目標を達成するために、コアコンポーネントのロードを簡素化する新しいMaven 3.3.1機能を使用しました。

コードとすべてのサンプルは、通常のover on Githubとして見つけることができます。