Elasticsearchのcomponent templateは左から順に適用される

サマリ

component templateは、index templateに配列で指定されますが、左から順に適用されます。

適用の動作は各フィールドを合成するイメージです。重複するフィールドの場合は値が上書きされ、重複するフィールドが無ければ追加されます。

https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-template.html#multiple-component-templates

環境

前回の記事と同様の環境です。

https://baubaubau.hatenablog.com/entry/2022/01/21/230451

また、RESTクライアントとして、vscodeの以下のプラグインを使いました。

https://github.com/hsen-dev/vscode-elastic

二つのcomponent templateを作成する

次の通り、二つのcomponent templateを作成します。

それぞれ、フィールドには重複するものと、しないものをあえて記述します。hostは両方に記述されますが、methodとurlは片方にしか記述がありません。

PUT _component_template/my_component_template_1
{
    "template": {
        "mappings": {
            "properties": {
                "host": {
                    "type": "keyword"
                },
                "method": {
                    "type": "keyword"
                }
            }
        }
    }
}

PUT _component_template/my_component_template_2
{
    "template": {
        "mappings": {
            "properties": {
                "host": {
                    "type": "text"
                },
                "url": {
                    "type": "keyword"
                }
            }
        }
    }
}

これらのcomponent templateを使って、index templateを作成します。

PUT _index_template/my_index_template
{
    "index_patterns": ["access*"],
    "composed_of": ["my_component_template_1", "my_component_template_2"]
}

indexを作成しmappingを確認すると、component templateが指定された順番に適用されていることがわかります。

PUT accesslog-20220101/

GET accesslog-20220101/_mapping

{
    "accesslog-20220101": {
        "mappings": {
            "properties": {
                "host": {
                    "type": "text"
                },
                "method": {
                    "type": "keyword"
                },
                "url": {
                    "type": "keyword"
                }
            }
        }
    }
}

重複して指定されていたhostフィールドは左から順に合成されたため、typeがtextになっています。

それ以外のフィールドは重複していないため、指定したtype通りに設定されています。

Elasticsearchのインデックステンプレートのpriorityで優先度を変えてみる

重複した内容のインデックステンプレートを作成する場合について、少しだけ調べてみました。

サマリ

priorityで設定された値が大きいものが、適用されます。

https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-template.html

環境

次のDockerComposeファイルを使って、elasticsearchを起動しました。

version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.16.2
    ports:
      - 9200:9200
      - 9300:9300
    environment:
      - discovery.type=single-node
      - action.destructive_requires_name=true
    networks:
      - elastic
  ki01:
    image: docker.elastic.co/kibana/kibana:7.16.2
    environment:
      ELASTICSEARCH_HOSTS: "http://es01:9200"
    ports:
      - 5601:5601
    networks:
      - elastic
networks:
  elastic:
    driver: bridge

インデックステンプレートを2つ作り、priorityの動作を確かめる

1つ目のインデックステンプレートを作ります。priorityの指定がない場合、priotiyは最低値の0と解釈されます。

priorityの値がelasticsearchで自動的に生成されることはありません。

こちらのインデックステンプレートには、hostをtextとしてマッピングします。

PUT /_index_template/my_template_1
{
    "index_patterns": "accesslog-*",
    "template": {
        "mappings": {
            "properties": {
                "host": {
                    "type": "text"
                }
            }
        }
    }
}

2つ目のインデックステンプレートを作ってみます。あえて、priorityを指定せず、同じインデックスパターンで作成をしてみます。

PUT /_index_template/my_template_2
{
    "index_patterns": "accesslog-*",
    "template": {
        "mappings": {
            "properties": {
                "host": {
                    "type": "keyword"
                }
            }
        }
    }
}

すると、同じ条件のインデックスパターンで、同じpriorityのインデックステンプレートは作成できないと言われます。

{
    "error": {
        "root_cause": [
            {
                "type": "illegal_argument_exception",
                "reason": "index template [my_template_2] has index patterns [accesslog-*] matching patterns from existing templates [my_template_1] with patterns (my_template_1 => [accesslog-*]) that have the same priority [0], multiple index templates may not match during index creation, please use a different priority"
            }
        ],
        "type": "illegal_argument_exception",
        "reason": "index template [my_template_2] has index patterns [accesslog-*] matching patterns from existing templates [my_template_1] with patterns (my_template_1 => [accesslog-*]) that have the same priority [0], multiple index templates may not match during index creation, please use a different priority"
    },
    "status": 400
}

と、言うわけで、priorityを高くしてもう一度リクエストを飛ばし、作成します。

こちらのインデックステンプレートには、hostをkeywordとしてマッピングします。

PUT /_index_template/my_template_2
{
    "index_patterns": "accesslog-*",
    "template": {
        "mappings": {
            "properties": {
                "host": {
                    "type": "keyword"
                }
            }
        }
    },
    "priority": 1
}

priorityが大きいインデックステンプレートが使われるか確かめる

インデックスを作成し、どちらのインデックステンプレートが作成されるか確かめます。

PUT /accesslog-20220117

GET /accesslog-20220117/_mapping
{
    "accesslog-20220117": {
        "mappings": {
            "properties": {
                "host": {
                    "type": "keyword"
                }
            }
        }
    }
}

hostがkeywordとなっているので、priorityが大きいmy_template_2が適用されたことがわかりました。

Elasticsearchのindex templateを試す

index templateを使うと、インデックスの各種設定値をあらかじめ決めておくことができます。

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-templates.html

index templateは、複数のcomposed templateを含めることができます。composed templateはインデックス設定項目のうち、次の内容を再利用できるよう独立して定義できるものです。

  • mappings
  • settings
  • aliases

composed templateは使いまわすことができるので、共通の設定値を定義しておくといった使い方ができそうです。

次のdocker-compose.ymlを使用して、index templateとcomposed templateを使ってみます。

version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.16.2
    ports:
      - 9200:9200
      - 9300:9300
    environment:
      - discovery.type=single-node
      - action.destructive_requires_name=true
    networks:
      - elastic
  ki01:
    image: docker.elastic.co/kibana/kibana:7.16.2
    environment:
      ELASTICSEARCH_HOSTS: "http://es01:9200"
    ports:
      - 5601:5601
    networks:
      - elastic
networks:
  elastic:
    driver: bridge

kibanaのDevTools画面から操作しました。

composed templateを定義します。

PUT _component_template/component_template1
{
  "template": {
    "mappings": {
      "properties": {
        "@timestamp": {
          "type": "date"
        }
      }
    }
  }
}

定義を確認します。

GET _component_template/component_template1

// レスポンス
{
  "component_templates" : [
    {
      "name" : "component_template1",
      "component_template" : {
        "template" : {
          "mappings" : {
            "properties" : {
              "@timestamp" : {
                "type" : "date"
              }
            }
          }
        }
      }
    }
  ]
}

この、 component_template1 を使って、index templateを定義します。

PUT _index_template/template1
{
  "index_patterns": ["te*"],
  "template": {
    "settings": {
      "number_of_shards": 3
    },
    "mappings": {
      "_source": {
        "enabled": true
      },
      "properties": {
        "host_name": {
          "type": "keyword"
        },
        "created_at": {
          "type": "date",
          "format": "strict_date"
        }
      }
    }
  },
  "composed_of": ["component_template1"]
}

index templateは次の設定にしました。

  • index_patterns : このindex templateが適用される、インデックス名です。ワイルドカードで、 te から始まるインデックスに対して、適用されるようにしました。複数のインデックス名を指定することもできます。
  • template.settings.number_of_shards : シャード数を3にしています。
  • template.mappings : フィールドのデータ型を定義します。 created_at には、日付の型を定義し、フォーマットで strict_date を指定しました。
  • composed_of : composed indexを列挙します。

インデックスを作成し、各設定を見てみます。

PUT test_index1

GET test_index1/_mapping

// レスポンス
{
  "test_index1" : {
    "mappings" : {
      "properties" : {
        "@timestamp" : {
          "type" : "date"
        },
        "created_at" : {
          "type" : "date",
          "format" : "strict_date"
        },
        "host_name" : {
          "type" : "keyword"
        }
      }
    }
  }
}

index templateとcomposed templateで設定した各項目が反映されているのがわかります。

Elasticsearchのクラスタ構成を試す

クラスタを組んでみます。

ノードは3つで、それぞれをmaster-eligable、data、Ingestの役割を割り当ててみます。

Node | Elasticsearch Guide [7.16] | Elastic

環境はdocker-composeを使いました。

$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c

以下、 docker-compose.yml です。

version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
    ports:
      - 9200:9200
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
    networks:
      - elastic
  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
    networks:
      - elastic
  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
    networks:
      - elastic
networks:
  elastic:
    driver: bridge

それぞれのコンテナの環境変数で定義している、 discovery.seed_hostsクラスタを構成する時に相手を探しに行く先になります。ホスト名、またはIPアドレスを指定します。ポートを省略すると、9300と解釈されます。

https://www.elastic.co/guide/en/elasticsearch/reference/7.16/important-settings.html#unicast.hosts

cluster.initial_master_nodesクラスタを初期構築する際に、 master を決める投票に参加するノードを指定します。

https://www.elastic.co/guide/en/elasticsearch/reference/7.16/important-settings.html#initial_master_nodes

docker-compose up で起動させ、動作確認してみます。

$ curl -XGET http://localhost:9200/_cluster/health?pretty
{
  "cluster_name" : "es-docker-cluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 0,
  "active_shards" : 0,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

"status" : "green" となっているので、正しく起動できたようです。

Qodanaを試す

JetBrains製の静的解析ツールが出ていたので、試してみました。

今の所、以下の言語に対応しているみたいです。Java以外はEAPなんですね。

今回はJavaで試します。

Qodana for JVM

Qodana for JVM はサーバーサイドKotlinかJavaを解析できるようです。Scalaは近日公開とのこと。

手元のKotlinのプロジェクトで試してみます。

Dockerで動かします。

Qodana for JVM Docker image | Qodana

docker run --rm -it -p 8080:8080 \
  -v <source-directory>/:/data/project/ \
  -v <output-directory>/:/data/results/ \
  jetbrains/qodana-jvm-community --show-report

実際に動かしてみます。

docker run --rm -it -p 8080:8080 \
  -v "$(pwd)"/direct/:/data/project/ \
  -v "$(pwd)"/report/:/data/results/ \
  jetbrains/qodana-jvm-community --show-report

/data/project/ にプロジェクトを配置すれば、解析されます。結果は /data/results/ に吐き出されます。

解析には少し(四分程度)かかりました。時間はプロジェクトの規模に関係しているかもしれません。また、解析にはメモリを大量に消費するようです。問題があればDockerのメモリ割り当てを増やす必要があるかもしれません。

By using this Docker image, you agree to the Qodana Community Linters Agreement (https://www.jetbrains.com/legal/docs/agreements/qodana/community-linters/) and JetBrains privacy policy (https://www.jetbrains.com/legal/docs/privacy/privacy/).
                                        
     QQQQQQQ      DDDDDDDDDDD           Qodana for JVM Community linter
   QQ:::::::QQ    D::::::::::DDD        Analyze project written in Java and Kot
 QQ:::::::::::QQ  D:::::::::::::DD      lin
Q::::::QQQ::::::Q DDD::::DDDDD::::D     To see the complete list of supported t
Q:::::O   Q:::::Q   D::::D    D::::D    echnologies and languages,
Q::::O     Q::::Q   D::::D     D::::D   visit the Qodana (https://www.jetbrains
Q::::O     Q::::Q   D::::D     D::::D   .com/qodana) documentation.
Q::::O   QQQ::::Q   D::::D     D::::D   Contact us at
Q:::::O  Q::::::Q   D::::D    D:::DD    qodana-support@jetbrains.com
 QQ::::QQ::::::Q  DDD::::DDDDD::DD      Or via our issue tracker:
   QQ:::::::::Q   D::::::::::DDD        https://jb.gg/qodana-issue
     QQQQQQQ:::QQ DDDDDDDDDDD           Or share your feedback in our Slack:
            QQQQQQ                      https://jb.gg/qodana-slack!
                                        
Starting up IntelliJ IDEA 2021.2.3 (build QDJVMC-212.5672.90) ...done.
Preparing for the Project opening stage ...
(Project opening) done.                                                         
The Project opening stage completed in 4 s 198 ms
Initializing project...Inspecting with the 'qodana.starter' profile
Loaded the 'qodana.sanity' shared project profile
The 'qodana.sanity' profile is configured for sanity checks
The 'qodana.recommended' profile is configured for promo checks
 0%
Preparing for the Project configuration stage ...
(Project configuration) Keep running Project configuration ... so far 4 m 0 s 9 
The Project configuration stage completed in 4 m 24 s 211 ms
Preparing for the Project analysis stage ...
(Project analysis) Analyzing code 94% [QuestionApplicationService.kt]           
The Project analysis stage completed in 4 s 608 ms
---- Qodana - Detailed summary ----

Analysis results: 1 problems detected

Grouping problems by severity: Note - 1
Name                     Severity Count problems
Implicit `Nothing?` type note     1      
-----------------------------------
2021/12/18 03:26:32 IDEA exit code: 0
2021/12/18 03:26:32 Generating html report ...
Generating final reports...
The project doesn't contain qodana.yaml config file
Done
2021/12/18 03:26:33 Serving report on http://localhost:8080 ...

今回は予め意図的に問題のあるコードを忍ばせておきました。結果、その箇所が検出されたようです。

--show-report 引数をつけたので、ブラウザからレポートを確認できます。

f:id:bau1537:20211218123150p:plain

どのような問題が何件あるのか、問題の箇所はどこか、画面で確認できます。

「Open file in」からIntelliJで該当箇所を直接開けます。便利ですね。

レポート画面は /data/results/ に生成されたHTMLからでも確認できるのでDockerコンテナを終了した後でも確認できます。CIに組み込む場合はこのファイルをアーカイブすると、結果を保存できますね。

maven-resources-pluginのエンコーディングの警告に対処する

  • プロジェクトをビルドしていたらふと気になったので。
  • こんな警告が出ていました。
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ direct-core ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

MavenのArchetypesについて

環境

$ mvn --version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.11, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.4.0-89-generic", arch: "amd64", family: "unix"

Archetypeとは?

  • シンプルに言うと、プロジェクトのテンプレートツールキットのこと
  • 組織はArchetypeを使うことで、プロジェクトのベストプラクティスに従った構成をすばやく構築できる
  • Archetypeは既存で定義されているものもあるし、自分で定義して配布することもできる

Maven Archetype Pluginとは?

使ってみる

  • Project creation を参考に使ってみる
  • 通常、archetypeはリモートリポジトリから取得される
    • 特に設定がされていなければCentralRepositoryが参照されるはず
    • それ以外のリポジトリを参照したければ settings.xml などで定義すること
  • archetype:generateインタラクティブモードでプロジェクトの生成を開始できる
    • 出力の一部がドキュメント違うので、ドキュメントは少し古いのかもしれない
$ mvn archetype:generate
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:3.2.0:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:3.2.0:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO] 
[INFO] 
[INFO] --- maven-archetype-plugin:3.2.0:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: remote -> am.ik.archetype:elm-spring-boot-blank-archetype (Blank multi project for Spring Boot + Elm)
2: remote -> am.ik.archetype:graalvm-blank-archetype (Blank project for GraalVM)
3: remote -> am.ik.archetype:graalvm-springmvc-blank-archetype (Blank project for GraalVM + Spring MVC)
4: remote -> am.ik.archetype:graalvm-springwebflux-blank-archetype (Blank project for GraalVM + Spring MVC)
5: remote -> am.ik.archetype:maven-reactjs-blank-archetype (Blank Project for React.js)
6: remote -> am.ik.archetype:msgpack-rpc-jersey-blank-archetype (Blank Project for Spring Boot + Jersey)
~~ 以下略 ~~
  • インタラクティブモードでは大量にarchetypeが出力される
  • 最終的に次のような文言とともにユーザーの入力待機状態となる
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains):
  • この状態で、特定のarchetypeの番号を入力すると、プロジェクトの作成に移る
  • また、大量のarchetypeをフィルタして再表示させることもできる
    • フィルタのフォーマットは文言通り、 [groupId:]artifactId となる
    • 例えば org.apache: とすると、groupIdが一致するものがフィルタされ表示される
    • また simple とすると、artifactIdにsimpleが含まれるものがフィルタされ表示される
    • さらに org.apache:simple とすると、groupIdが org.apache でartifactIdに simple が含まれるものがフィルタされ表示される
  • 例えば次のような出力になる
    • 一覧表示させながら絞り込んでいきたい時、この機能は役立ちそうだ
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : org.apache:simple
Choose archetype:
1: remote -> org.apache.flex.flexjs.framework:flexjs-simple-application-archetype (Maven archetype for creating FlexJS Maven project for building a simple FlexJS application with both Flash and JavaScript output.)
2: remote -> org.apache.flex.flexjs.framework:flexjs-simple-application-pure-js-archetype (Maven archetype for creating FlexJS Maven project for building a simple FlexJS application with only JavaScript output.)
3: remote -> org.apache.flex.flexjs.framework:flexjs-simple-application-pure-swf-archetype (Maven archetype for creating FlexJS Maven project for building a simple FlexJS application with only Flash output.)
4: remote -> org.apache.flex.flexjs.framework:flexjs-simple-library-archetype (Maven archetype for creating FlexJS Maven project for building a simple FlexJS library.)
5: remote -> org.apache.flex.flexjs.framework:flexjs-simple-typedef-archetype (Maven archetype for creating FlexJS Maven project for building a simple FlexJS typedef library.)
~~ 以下略 ~~
  • さらに、 -Dfilter で最初からフィルタを指定して表示させることもできる
  • 例えば以下の通り
$ mvn archetype:generate -Dfilter=org.apache:simple
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:3.2.0:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:3.2.0:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO] 
[INFO] 
[INFO] --- maven-archetype-plugin:3.2.0:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: remote -> org.apache.flex.flexjs.framework:flexjs-simple-application-archetype (Maven archetype for creating FlexJS Maven project for building a simple FlexJS application with both Flash and JavaScript output.)
2: remote -> org.apache.flex.flexjs.framework:flexjs-simple-application-pure-js-archetype (Maven archetype for creating FlexJS Maven project for building a simple FlexJS application with only JavaScript output.)
3: remote -> org.apache.flex.flexjs.framework:flexjs-simple-application-pure-swf-archetype (Maven archetype for creating FlexJS Maven project for building a simple FlexJS application with only Flash output.)
4: remote -> org.apache.flex.flexjs.framework:flexjs-simple-library-archetype (Maven archetype for creating FlexJS Maven project for building a simple FlexJS library.)
5: remote -> org.apache.flex.flexjs.framework:flexjs-simple-typedef-archetype (Maven archetype for creating FlexJS Maven project for building a simple FlexJS typedef library.)
~~ 以下略 ~~
  • ここでarchetypeを選んだら、必要なプロパティ(groupId,artifactId,versionなど)を入力してプロジェクトを作成する
  • 例えば以下の通り
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 9
Choose org.apache.maven.archetypes:maven-archetype-simple version: 
1: 1.3
2: 1.4
Choose a number: 2: 
Define value for property 'groupId': org.demo
Define value for property 'artifactId': simple
Define value for property 'version' 1.0-SNAPSHOT: : 
Define value for property 'package' org.demo: : 
Confirm properties configuration:
groupId: org.demo
artifactId: simple
version: 1.0-SNAPSHOT
package: org.demo
 Y: : Y
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: maven-archetype-simple:1.4
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.demo
[INFO] Parameter: artifactId, Value: simple
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: org.demo
[INFO] Parameter: packageInPathFormat, Value: org/demo
[INFO] Parameter: package, Value: org.demo
[INFO] Parameter: groupId, Value: org.demo
[INFO] Parameter: artifactId, Value: simple
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Project created from Archetype in dir: /home/bookstore/IdeaProjects/demo-maven-archetype/simple
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  03:51 min
[INFO] Finished at: 2021-11-07T16:52:51+09:00
[INFO] ------------------------------------------------------------------------
$ tree .
.
└── simple
    ├── pom.xml
    └── src
        ├── main
        │   └── java
        │       └── org
        │           └── demo
        │               └── App.java
        ├── site
        │   └── site.xml
        └── test
            └── java
                └── org
                    └── demo
                        └── AppTest.java

11 directories, 4 files
  • pom.xml は以下の内容
<?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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.demo</groupId>
  <artifactId>simple</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>simple</name>
  <description>A simple simple.</description>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

  <reporting>
    <plugins>
      <plugin>
        <artifactId>maven-project-info-reports-plugin</artifactId>
      </plugin>
    </plugins>
  </reporting>
</project>

バッチモードでプロジェクトを作成する

  • 上記のように、インタラクティブにプロジェクトを作ることもできるが、時には必要なプロパティを最初から指定したいときもある
  • そんなときはバッチモードが使用できる
    • Generate project in batch mode
    • -B をつけるとバッチモードでプラグインが起動する
    • 必要なプロパティをそれぞれ -D で渡す
      • archetypeGroupId, archetypeArtifactId, archetypeVersion はarchetypeによらず必要になる
      • groupId, artifactId, version, package もそれぞれ必要となるがそれ以外にも必要なプロパティがある場合がある
        • 詳しくはarchetypeのドキュメントを読めとのこと
  • 具体的には下記のようにして使用する
$ mvn archetype:generate -B \
> -DarchetypeGroupId=org.apache.maven.archetypes \
> -DarchetypeArtifactId=maven-archetype-simple \
> -DarchetypeVersion=1.4 \
> -DgroupId=org.demo \
> -DartifactId=archetype \
> -Dversion=SNAPSHOT-1.0 \
> -Dpackage=org.demo
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:3.2.0:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:3.2.0:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO] 
[INFO] 
[INFO] --- maven-archetype-plugin:3.2.0:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode
[INFO] Archetype repository not defined. Using the one from [org.apache.maven.archetypes:maven-archetype-simple:1.4] found in catalog remote
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: maven-archetype-simple:1.4
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.demo
[INFO] Parameter: artifactId, Value: archetype
[INFO] Parameter: version, Value: SNAPSHOT-1.0
[INFO] Parameter: package, Value: org.demo
[INFO] Parameter: packageInPathFormat, Value: org/demo
[INFO] Parameter: package, Value: org.demo
[INFO] Parameter: groupId, Value: org.demo
[INFO] Parameter: artifactId, Value: archetype
[INFO] Parameter: version, Value: SNAPSHOT-1.0
[INFO] Project created from Archetype in dir: /home/bookstore/IdeaProjects/demo-maven-archetype/archetype
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.684 s
[INFO] Finished at: 2021-11-09T14:00:27+09:00
[INFO] ------------------------------------------------------------------------