注目イベント!
春の新人向け連載企画開催中
新人エンジニアの皆さん、2024春、私たちと一緒にキャリアアップの旅を始めませんか?
IT業界への最初の一歩を踏み出す新人エンジニアをサポートする新連載スタート!
mameyose

今さら聞けないMaven – 実行オプションの固定化

| 6 min read
Author: toshio-ogiwara toshio-ogiwaraの画像

Mavenでは多数の条件をmvnコマンドのオプションで指定することが多いですが、指定するオプションにはプロジェクトや環境が同じであればに常に同じとなるオプションがあるため、オプションを固定化したい場合があったりします。また 「ローカルリポジトリの分割」で紹介したような長いオプションを都度指定するのが面倒だったりもします。このような場合、実行コマンドをbatファイルやシェルスクリプトでスクリプト化する方法がよく行われますが、Mavenにはオプションを固定化し実行ごとに必要なる入力を省略可能にする機能があります。今回はこのMavenのオプションを固定化する機能を紹介します。

オプションの種類(予備知識)

#

オプションを固定化する方法はその種類によって分かれているため、本題に入る前にMavenの実行時に指定するオプションの種類について簡単に説明します。

Mavenの実行時に指定するオプションは大きく次の2つに大別できます。

  • VMオプション
  • Mavenオプション

Mavenはご存じのとおりJavaVM上で実行されますが、VMオプションはこのMavenを実行する土台となるJavaVMに対するオプションとなります。具体的には最大ヒープサイズを指定する-Xmx1024mなどjavaコマンドで定義されているオプションとなります。

これに対してMavenオプションはMaven機能に対するオプションとなります。この具体的なものとしてはプロファイルを指定する-Pオプションやバッチモードで実行する-Bオプションなどmvnコマンドで定義されているオプションとなります。

VMオプションはmvnコマンドの引数で直接指定できない

Mavenをよくご存じの方は-Xmx1024mなどのVMオプションってmvnコマンドで指定できたっけ?と思うかもしれませんがその疑問は正しいです。VMオプションはmvn -Xmx1024m clean packageのようにmvnコマンドの引数で直接指定することはできません。VMオプションを指定する場合は次の「VMオプションの固定化」で紹介する方法で指定する必要があります。この点はMavenオプションと異なり混乱しやすいところですので留意が必要です。

VMオプションの固定化

#

本題に入ってまずはVMオプションを固定化する方法ですが、これには次の2つの方法があります。

  • 環境変数MAVEN_OPTSによる設定
  • .mvn/jvm.configによる指定

例えば、最大ヒープサイズを2GB(2048MB)、最小ヒープサイズを1GB(1024MB)でMavenを実行する指定をMAVEN_OPTSを使って行う場合は、次のようになります。

export MAVEN_OPTS="-Xmx2048m -Xms1024m"
mvn clean compile

これと同じ内容を.mvn/jvm.configで指定する場合は、プロジェクト直下に.mvn/jvm.configファイルを作成し、そのファイルに固定化するオプションを次のようにそのまま記述します。

-Xmx2048m -Xms1024m

なおMAVEN_OPTSjvm.configの指定は併存可能性です。
現実的な例ではないですが、MAVEN_OPTS-Xmx2048mjvm.config-Xms1024mを設定した場合、実行時にはこの2つが連結され、JavaVMには-Xmx2048m -Xms1024mが渡るようになっています。

このことから、この2つの使い分けは、プロジェクトごとに共通となる設定はビルド担当者が.mvn/jvm.configを作成してプロジェクトのリポジトリにコミットしておき、環境変数MAVEN_OPTSはその環境ごとに個別に設定するといった、プロジェクトの共通設定と環境ごとの個別設定になると思います。

同じオプションが指定された場合の優先度は不定

MAVEN_OPTS-Xmx2048mが設定されているのに対してjvm.configにも最大ヒープサイズを指定する-Xmx1024m が設定されている場合、2048mと1024mのどちらが有効になるかはMavenのマニュアルにも明記されていません。また、mvnコマンドの実体のシェルスクリプトを確認しても、単にMAVEN_OPTSjvm.configの設定を連結しているだけで、そのどちらが有効となるかはJavaVM次第で結果は不定となります。したがって、プロジェクトの共通的なMAVEN_OPTSの設定を環境個別のjvm.configの設定で上書きするといったことはできないので注意しましょう。

Mavenオプションの固定化

#

次にMavenオプションを固定化する方法ですが、これはVMオプションと同様に次の2つになります。

  • 環境変数MAVEN_ARGSによる設定
  • .mvn/maven.configによる指定
MAVEN_ARGSが使えるのはMaven 3.9.0から

環境変数MAVEN_ARGSの機能が入ったのはMaven 3.9.0からとなります。それ以前のバージョンではMavenオプションを固定化する方法は.mvn/maven.configによる指定のみとなります。

VMオプションと同様に例をもとに説明すると、例えばMavenのバージョン情報を出力する-Vオプションとリモートとローカルの取得元別にアーティファクトを別々に格納するようにする-Daether.enhancedLocalRepository.splitオプション[1]が常に指定されるようにしたい場合、設定は次のようになります。

  • 環境変数MAVEN_OPTSによる指定
export MAVEN_ARGS="-V -Daether.enhancedLocalRepository.split"
 mvn clean compile

  • maven.configの設定内容
-V
-Daether.enhancedLocalRepository.split

maven.configjvm.configと同様に.mvnディレクトリの直下にファイルを作成して設定を行います。

maven.configの改行は3.9.0より以前では不要

Maven 3.9.0以降ではmaven.configに複数のオプションを指定する場合、上述の例のように1行に1オプションとなるように記述する必要がありますが、3.9.0より以前では1行にすべてのオプションを記述する必要があります。このため、上述の例は3.9.0より以前では次のように記述します。

-V -Daether.enhancedLocalRepository.split
pomのプロパティを上書きする-DオプションはMavenオプション

pomのpropertiesで定義したプロパティはmvnコマンドの-Dオプションで書き換えることができます。例えば、次のような設定があった場合、

<project xmlns=...>
  ...
  <properties>
    <sample.arg>arg1</sample.arg>
  </properties>
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>3.1.0</version>
        <configuration>
          ...
          <arguments>
            <argument>${sample.arg}</argument>
          </arguments>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project> 

pomに定義されたsample.argは次のようにmvnコマンドの-Dオプションで値を書き換えることができます。

mvn clean compile -Dsample.arg=hello

この場合の-Dオプションはシステムプロパティの設定を行うjavaコマンドの-Dオプションではなく、mvnコマンドが持つpomのプロパティを書き換える-Dオプションとなります。したがって、pomのプロパティを書き換える-Dオプションを固定化する場合はVMオプションを固定化するMAVEN_OPTSjvm.configではなく、Mavenオプションを固定化するMAVEN_ARGSmaven.configに指定する必要があります。これはオプションを固定化する際の固有な扱いではなく、Mavenのhelpにもあるとおり、MavenがJavaVMと同じ-Dオプションを別の用途で定義しているためとなります。

mvn --help
> usage: mvn [options] [<goal(s)>] [<phase(s)>]
> 
> Options:
>  -D,--define <arg>       Define a user property
> ...

MAVEN_ARGSmaven.configの併存と双方に同じオプションが指定された場合の扱いはVMオプションと同じとなりますが、VMオプションはmvnコマンドで直接指定することができないのに対し、Mavenオプションは(通常行っているように)mvnコマンドでオプションを都度指定することができるといった違いがあります。

このため、次のようなオプション指定を行うコマンドがあった場合、

mvn clean compile exec:java -P product -V -Daether.enhancedLocalRepository.split

-V-DオプションをMAVEN_ARGSmaven.configで固定化することで次のように実行の都度指定が変わるものだけを指定して実行することができるようになります。

mvn clean compile exec:java -P product

まとめ

#

記事ではMaven実行時のオプション指定を固定する方法として4つを説明しましたが、この4つの用途は次のようにまとめることができます。

VMオプション Mavenオプション
プロジェクトごとの設定 .mvn/jvm.config .mvn/maven.config
環境ごとの設定 MAVEN_OPTS MAVEN_ARGS

Mavenが持つオプションの固定化機能はbatファイルやシェルスクリプトによるスクリプト化よりも簡潔に設定することができるため、ここぞ!というオプション指定があった場合は是非使ってみたいと思います。


参照資料


  1. 「今さら聞けないMaven – 3.9.0で追加されたローカルリポジトリの分割 | 豆蔵デベロッパーサイト」を参照 ↩︎

豆蔵では共に高め合う仲間を募集しています!

recruit

具体的な採用情報はこちらからご覧いただけます。