LoginSignup
3
0

Maven覚書

Last updated at Posted at 2023-11-07

はじめに

初めてjavaを使って開発する機会がありビルドツールとしてMavenを採用しました。
開発環境を設定する際になんとなくで使用していたため、自分の理解のためにまとめてみました。

Mavenとは

MavenはApatche Software Foundationで開発されたソフトウェアプロジェクト管理ツールです。読み方は「メイヴェン」。Project Object Model(POM)と呼ばれるXML形式のファイル情報に基づき、プロジェクトの新規作成からコンパイル、テスト、パッケージング、配備などのプロジェクトのライフサイクルやライブラリの依存関係の管理などが行えます。理解ツールという面もあり、Mavenを利用したプロジェクトではビルドプロセスやプロジェクトの構成などがデフォルトで決まっているため、全体把握がしやすいというメリットがあります。

Mavenのアーキテクチャ
image.png
参考
Mavenを使用するとコンパイルやテストなどプロジェクトのライフサイクルの作業をコマンド一つで実行することができます。リモートリポジトリとローカルリポジトリは使用されるプラグインとライブラリが配置される場所になります。Mavenコマンド実行時に必要なプラグインやライブラリがリモートリポジトリからローカルリポジトリにダウンロードされ参照されます。

インストール

こちらからzipをインストールします。
現在(2023/11)の最新バージョンは3.9.5です。
image.png
任意の場所にzipの解凍後**\apache-maven-3.9.5\binをシステム環境変数Pathに追加してください。
mvn -vを実行しバージョン情報が表示されたらOKです。
image.png

補足
MavenにはMaven Wrapperと呼ばれる、Mavenを自動ダウンロードし各操作ができるラッパーがあります。各開発者わざわざMavenをインストールする必要がなくなるので、実際のプロジェクトではMaven Wrapperを使用もありだと思います。Maven Wrapperを使用する場合は、mvnコマンドの代わりにmvnw.cmdを叩く形になります。実際に開発ではMaven Wrapperを使用していました。

プロジェクトの作成

新しくMavenのプロジェクトを立ち上げるにはArchetype Pluginを使用してテンプレートからプロジェクトを作成するのが手っ取り早いです。例えば以下のようなコマンドを実行します。

$ mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

プラグインにはゴールと呼ばれる実行される処理がいくつか存在します。上記コマンドではarchetypeプラグインのgenerateゴールを実行しています。-Dではその処理に対するパラメータを指定でき、mavenプロジェクトで必要なgroupIdcom.mycompany.appartifactIdmy-appに指定しています。またarchetypeにはいくつか種類が存在しており、今回はmaven-archetype-quickstartと呼ばれるarchetypeが指定されます。archetypeはプロジェクトに合わせて選択する感じになると思います。
archetype一覧

※補足
vscodeを使用して開発を行う場合はMaven for Javaを使うとGUIベースでテンプレートを作成できます。

ディレクトリ構造

Mavenでは標準となるディレクトリ構造が決まっており、それに従うことが推奨されています。ディレクトリ構造を考える手前も減りますし、Mavenプロジェクトであれば同一のディレクトリ構造となるので他プロジェクトへの参画もしやすいというメリットもあるので、特に問題がなければ従うのが良いと思います。
例えば先ほどのコマンドでは以下のような構成でプロジェクト作成されています。

my-app
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- com
    |           `-- mycompany
    |               `-- app
    |                   `-- App.java
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- app
                        `-- AppTest.java

以下がディレクトリ構造の決まりです。

ディレクトリ 説明
src/main/java アプリケーション・ライブラリのソースコード
src/main/resources アプリケーション・ライブラリのリソース
src/main/filters リソースに適用するフィルタ
src/main/webapp Webアプリケーションのソース
src/test/java テストのソースコード
src/test/resources テストのリソース
src/test/filter テストリソースに適用するフィルタ
src/it 統合テスト用
src/assembly アセンブリ記述子。 配布用ファイル (zip や tar.gz など) の作成に関する情報。
src/site サイトの作成に必要なファイル

Introduction to the Standard Directory Layout

POM

pom.xmlはプロジェクトに関する情報を持つMavenにおいて核となるXML形式のファイルです。プロジェクトの依存関係やビルド手順、プラグイン、リポジトリなどの設定はすべてここに記述されます。
先ほどのコマンドでは以下のような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>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>my-app</name>
  <!-- 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>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://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>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <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>
      </plugins>
    </pluginManagement>
  </build>
</project>

上記のpom.xmlの構成は大まかな内容は以下になります。

パラメータ 説明
project 最上位要素。必須。
modelVersion POMのバージョン。必須。
groutId プロジェクトを作成した組織またはグループの一意の識別子を指定する。依存関係解決のなど一意に認識するために使用されたりする。必須。
artifactId 一次成果物の一意なベース名を指定する。パッケージングの際は{artifactId}-{version}.jarの形で生成される。必須。
version バージョン情報。SNAPSHOTは開発中を意味する。必須。
name プロジェクトの名前。Mavenで生成されたドキュメント内で使用される。
url プロジェクトのurl。Mavenで生成されたドキュメント内で使用される。
properties pom内でアクセスできる値のプレースホルダーの指定ができる。プレースホルダの文字列はpluginで決められている場合もあれば、任意で指定する事もできる。上記では用意されているmaven.compiler.targetmaven.compiler.sourceのプロパティに対してjavaのバージョン情報が指定されている。
dependencies 依存関係を列挙する。上記ではjunitという単体テストライブラリが追加されている。
build ディレクトリ構造の宣言やプラグインの管理を行う。上記では各プラグインのバージョン指定をしている。

pomにはSuper Pomと呼ばれるデフォルトのpomが存在します。プロジェクトのpomで値の指定がない場合は、このSuper Pomの値が継承されます。

POM Reference
Introduction to the POM
Super POM

ビルドライフサイクル

Mavenではビルドのプロセスが明確に定義されています。ユーザーはコマンドで各プロセスを実行することができます。組み込みではdefaultcleansiteの三つのビルドサイクルが存在します。それぞれdefaultはデプロイ処理、cleanはクリーニング処理,siteはプロジェクトのWebサイト作成の処理をします。

フェーズ

ライフサイクルはいくつかのフェーズで構成されています。例えばdefaultのライフサイクルは以下のようなフェーズがあります。

フェーズ 説明
validate プロジェクトが正しく、必要な情報がすべて利用可能であることを検証する。
compile プロジェクトのソースコードをコンパイルする。
test コンパイルされたソースコードをテストする。
package コンパイルされたコードを取得しJARやWARなどの配布可能な形式にパッケージ化する。
verify 統合テストの結果に関するチェックを実行する。
install ローカルの他のプロジェクトの依存関係として使用するために、パッケージをローカルリポジトリにインストールする。
deploy ビルド環境で実行され、他の開発者やプロジェクトと共有するために最終パッケージをリモートリポジトリにコピーする。

Lifecycle Reference

実行

各フェーズを実行するには、mvn {フェーズ}で対象のフェーズまで実行がされます。
最初の実行では必要なすべてのプラグインと依存関係をリモートリポジトリからローカルリポジトリにダウンロードするため時間がかかります。二回目以降はローカルリポジトリから参照されるようになるため実行時間が短縮されます。
以下から主に使うであろうフェーズの説明を記載します。

compile

$ mvn compile

上記コマンドでコンパイルされたクラスはデフォルトで${project.basedir}/target/classesに配置されます。これもMavenが標準的なディレクトリ構成規約に従っています。

test

テストの実行

$ mvn test

テストを実行で使用されるsurefireプラグインは、特定の命名規則を持つファイルがテストとして識別されます。デフォルトでは以下のファイルが対象になります。
**/*Test.java
**/Test*.java
**/*TestCase.java
以下のファイルがデフォルトで除外されます。
**/Abstract*Test.java
**/Abstract*TestCase.java

テストコンパイルのみ

$ mvn test-compile

package

JARやWRAなどの成果物の生成

$ mvn package

上記コマンドでは${project.basedir}/targetにファイルが生成されます。デフォルトではJARファイルになります。上で作成したプロジェクトではmy-app-1.0-SNAPSHOT.jarというファイルが出来上がるはずです。

clean

$ mvn clean

${project.basedir}/targetを削除します。
また以下のようにcleanした後にpackage実行といった操作もできます。

$ mvn clean package

プラグイン

Mavenの処理はプラグインによって実行されています。例えばJARにパッケージングする場合は各フェーズでは以下のようなプラグインのゴールに紐づいています。pom.xmlでバージョンが指定されていなければ、最新のプラグインがダウンロードされて実行されます。

フェーズ プラグイン:ゴール
process-resources resources:resources
compile compiler:compile
process-test-resources resources:testResources
test-compile compiler:testCompile
test surefire:test
package jar:jar
install install:install
deploy deploy:deploy

何のプラグインが実行されているかは、フェーズ実行時に出力されている情報からも確認できます。
image.png
利用できるプラグイン一覧は以下参照。
Available Plugins

pomになにも記載しなければデフォルトの設定で各プラグインのゴールが実行されます。プラグインごとにさまざまなパラメータが用意されてるため、それぞれ設定するにはpom.xmlのbuild/plugins内で指定します。
以下ではcompiler pluginでターゲットとなるJDKのバージョンを指定しています。

 <build>
   <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-compiler-plugin</artifactId>
       <version>3.3</version>
       <configuration>
         <release>17</release>
       </configuration>
     </plugin>
   </plugins>
 </build>

Guide to Configuring Plug-ins
 

依存関係

必要な依存関係はすべてpom.xmlに記載していく必要があります。
上で作成したプロジェクトではJUnitが依存関係に含まれています。

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

ここでは依存関係ごとに、groupIdartifactIdversionscopeの少なくとも4つを定義する必要があります。groupIdartifactIdversionは対象のプロジェクトのpom.xmlで指定されているものと同じです。scopeパラメータではプロジェクトがどのタイミング依存関係を解決するかを以下のような選択肢から指定できます。

説明
compile デフォルト値。常に必要な場合。
provided コンパイルやテストでは必要だが、実行時には実行環境が提供してくれる場合。
runtime コンパイル時には必要なく実行時に必要な場合。
test テストのコンパイル・実行時に必要な場合。
system 依存関係がシステム(実行環境のJREやJDK)から提供されるものである事を示す。

Introduction to the Dependency Mechanism

リポジトリ

Mavenでは依存関係はリポジトリから参照されます。
デフォルトではリモートリポジトリはMaven Central Repositoryになります。またはMaven Central Repositoryに加えて使用する独自のリモートリポジトリ(社内だけで共通で使用できるリポジトリなど)も設定することもできます。ローカルリポジトリはMavenを実行するPC上のディレクトリ(デフォルトは${user.home}/.m2/repository)でリモートリポジトリからダウンロードされたライブラリが含まれます。
Introduction to Repositories

おわりに

Maven全体の理解を深めることができました。
このあたりを知っておけばひとまずは迷うことなくmavenを使用できると思います。ライブラリやプラグインの細かい設定などは必要に応じて各々ドキュメントを見に行くのがよいでしょう。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0