Maven 入門 | pom.xml ファイルの基本 | Maven の中核 pom.xml

Maven では、コマンドを使って簡単にプロジェクトを作成したりビルドしたりできる。例として作成したプロジェクトは、App.java というソースコードファイルがあるだけの非常に単純なものだった。

Maven の強みは、さまざまなライブラリやフレームワークなどを利用する場合でも、それらを Maven がまとめて管理してくれる点にある。このような「プロジェクト管理」を行うには、単に Maven コマンドを実行するだけでは不十分である。プロジェクトを管理している「ビルドファイル」について理解する必要がある。

プロジェクトフォルダを開くと、そこに “pom.xml” というファイルが含まれていることがわかる。POM は “Project Object Model” の略で、プロジェクトのさまざまな情報を扱うためのオブジェクトモデルである。pom.xml には、プロジェクト設定を XML タグで記述する。

では、基本的にどのようなソースコードが書かれているのか見てみよう。

<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>com.devkuma</groupId>
  <artifactId>SampleMavenApp</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SampleMavenApp</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

これが pom.xml の基本コードと言ってよい。不要なものを取り除くと、基本コードは次のようになる。

<project ... 省略 ...>

    <modelVersion>4.0.0</modelVersion>
    <groupId>グループ ID</groupId>
    <artifactId>アーティファクト ID</artifactId>
    <version>バージョン</version>
    <packaging>jar</packaging>
    <name>名前</name>

    <properties>
        ...... プロパティ情報 ......
    </properties>

    <dependencies>
        ...... 依存ライブラリ情報 ......
    </dependencies>

</project>

pom.xml では、すべての情報を <project> というルートタグの中に記述する。この <project> には xmlns、xmlns:xsi、xsi:schemaLocation など細かな属性がいくつか付いているが、これらは決まった値なので、そのままコピーして使えばよい。必要に応じて修正する部分は基本的にない。

その後は、必要な情報をタグとして記述していくだけである。それぞれの内容を整理してみよう。

プロジェクトの基本プロパティ

<project> タグの次には、プロジェクトに関する基本プロパティを設定するタグがある。これらはどのプロジェクトでもほぼ必要になるものなので、役割だけは正確に覚えておく。

<modelVersion>4.0.0</modelVersion>

POM モデルのバージョンである。これは “4.0.0” と設定する。当面このバージョンが変わることはない。

<groupId>グループ ID</groupId>

グループ ID である。プロジェクト作成時に入力した。作成者、会社、団体などを識別するためのものだ。

<artifactId>アーティファクト ID</artifactId>

アーティファクト ID は、プロジェクトに割り当てた固有 ID である。

<version>バージョン</version>

プログラムのバージョンである。基本的には 1.0-SNAPSHOT が設定されている。

<packaging>jar</packaging>

パッケージの種類として jar または zip を指定する。Web アプリケーションを開発する場合は war を指定することもできる。

<name>名前</name>

プログラム名である。多くの場合、アーティファクト ID をそのまま指定する。

<url>URL</url>

プロジェクトに関連する Web サイトの URL である。基本的には Apache Maven の Web サイトの URL が指定されている。

<properties>
    ...... プロパティ情報 ......
</properties>

この pom.xml で使用するプロパティ値などをまとめておく。これは必要に応じて記述する。基本的には次の 1 つだけが含まれている。

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

project.build.sourceEncoding というプロパティは、ソースコードの基本エンコーディングを表す。一般的には UTF-8 が設定されている。

<dependencies>
    ...... 依存ライブラリ情報 ......
</dependencies>

「依存ライブラリ」とは、このプログラムが参照するライブラリのことである。Java の基本システムライブラリは除外される。

最後に、<properties><dependencies> を除けば、プロジェクト作成時に入力したものが多い。各項目はプロジェクト作成時に自動で記録されるため、自分で編集することはほとんどない。役割を知っていれば十分である。

<dependencies> と <dependency>

生成された pom.xml の記述の中で、タグがかなり複雑な部分が 1 つあった。<dependencies> というタグである。

これは前述のとおり、依存ライブラリ情報を記述しておくためのものだ。ただし、記述するタグが階層的になっているため、かなりわかりにくいかもしれない。基本的には次のような形で記述する。

<dependencies>
    <dependency>... 省略 ...</dependency>
    <dependency>... 省略 ...</dependency>
    ...... 省略 ......
</dependencies>

<dependencies> は、依存ライブラリを 1 か所にまとめて記述するためのものだ。各依存ライブラリの情報は <dependency> タグを使って作成する。この <dependency> タグを必要な数だけ <dependencies> タグの中に記述する。

<dependency> タグ

ライブラリ情報を記述する <dependency> タグでは、タグの中にいくつかの情報を書いてライブラリを指定する。まとめると次のような形になる。

<dependency>
    <groupId>グループ ID</groupId>
    <artifactId>アーティファクト ID</artifactId>
    <version>バージョン</version>
    <scope>スコープ</scope>
</dependency>

グループ ID、アーティファクト ID、バージョンは、先ほどのプロジェクトと同じ考え方である。ライブラリも Maven プログラムとして作られている以上、グループ ID とアーティファクト ID が設定されている。これらを指定することで、どのライブラリを使うのかを判断できる。

ただし、<scope> は少し理解しにくいかもしれない。これは、そのライブラリが利用される範囲を指定するものである。範囲というとわかりにくいが、「どの場面で使うか」を表すものだ。アプリケーション実行時に使う場合は、特に指定しなくてもよい。特別な場合にだけ用意するものと考えてよい。

<dependency> タグの <scope>

dependency の下に含まれる項目で、その dependency が含まれる範囲を表すタイプである。scope の種類は次のとおりである。

  • compile:
    • デフォルトの scope である。入力しなくても標準で適用される。
    • すべての状況で含まれる。
  • provided
    • compile と同様に、すべての状況で使用される。
    • ただし、外部コンテナで標準提供される API の場合、provided に指定すると最終パッケージには含まれない。
    • たとえば Tomcat は Servlet API を標準で提供するため、Servlet API を provided に指定するとパッケージング時に除外される。
  • runtime
    • コンパイル時には不要で、実行時に必要な場合に使う。
    • ランタイムおよびテスト時の classpath には追加されるが、コンパイル時には追加されない。
    • test: テスト時だけ使用する。
  • system
    • provided と似ている。
    • システム上の特定 path を参照するように指定する。
    • Maven Central Repository は使用しない。
  • import
    • dependencyManagement セクションで pom の依存関係に対して使用する scope である。

JUnit ライブラリ

サンプルとして作成したプロジェクトでは、“JUnit” というライブラリ情報が <dependencies> に記述されている。これはユニットテストのための機能を提供する Java ライブラリである。Java でテストと言えば、多くの場合 JUnit を使用する。

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.1</version>
  <scope>test</scope>
</dependency>

このライブラリの情報は次のようになっている。

グループ ID: junit
アーティファクト ID: junit
バージョン: 3.8.1 (場合によって異なることもある)
スコープ: test

グループ ID とアーティファクト ID は固定で、それぞれ “junit” と指定されている。これが JUnit に割り当てられた値である。バージョンは、プロジェクト作成時に最低限のバージョンが設定されているはずだ。

scope は “test” になっている。これは、テスト実行時だけ利用されることを表す。実際にプログラムを実行するときには使用できない。したがって、プログラムをビルドしてパッケージングするときにも、この JUnit ライブラリは含まれない。

Maven では、プログラムのビルドやパッケージングなどを行うとき、必ずユニットテストも同時に実行される。このときテストライブラリが含まれていなければビルドは失敗する。したがって、標準で記述されている JUnit ライブラリの <dependency> タグは「Maven プロジェクトに必要なライブラリ設定」と言える。使わないからといって削除しないようにする。