疑問点
「:」でつないで実行するコマンドと、
$ mvn checkstyle:checkstyle
「:」なしで実行できるコマンドがある。
$ mvn test
この差は何か?
結論
- 「mvn checkstyle:checkstyle」は「ゴール」
- 「mvn test」は「フェーズ」
ゴールとは?
mavenのpluginそれぞれが提供する具体的な機能。
以下の形式で実行する。
$ mvn prefix:goal
例えば、echo-maven-pluginの場合、
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example.com</groupId>
<artifactId>sample</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>sample</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>echo-maven-plugin</artifactId>
<version>0.3.0</version>
<configuration>
<echos>
<echo>This is the Test Text </echo>
</echos>
</configuration>
</plugin>
</plugins>
</build>
</project>
以下の形式で、echo-maven-pluginが提供する機能を利用する。
$ mvn echo:echo
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building sample 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- echo-maven-plugin:0.3.0:echo (default-cli) @ sample ---
[INFO] This is the Test Text // <-ここがecho plugin の実行結果
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.147 s
[INFO] Finished at: 2017-07-31T20:48:17+09:00
[INFO] Final Memory: 8M/304M
[INFO] ------------------------------------------------------------------------
テストやビルドの具体的な処理も、全てpluginが提供している。
注意点
ゴールは指定したゴールしか実行できない。pluginによっては別のpluginの実行結果やコンパイル結果(classesファイル)が存在することを前提としたものがある(findbugsとか)。そのため、ゴール単体で利用するときは、実行順序に注意が必要。 後述するフェーズを利用すれば、この問題を解消できる。
フェーズとは?
mavenが用意している、ライフサイクル中の各ステップ。
validate - validate the project is correct and all necessary information is available compile - compile the source code of the project test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed package - take the compiled code and package it in its distributable format, such as a JAR. verify - run any checks on results of integration tests to ensure quality criteria are met install - install the package into the local repository, for use as a dependency in other projects locally deploy - done in the build environment, copies the final package to the remote repository for sharing with other developers and projects.
参考 Introduction to the Build Lifecycle
フェーズ自体は具体的な処理をせず、フェーズに登録されたpluginのゴールを呼びだすだけ。もし複数のpluginのゴールが登録されていれば、複数のpluginのゴールを呼びだす。
したがってMavenを利用してビルドやテストをするためには、各フェーズにpluginを登録する必要がある。が、Mavenは親切なので、デフォルトでいくつかのpluginのゴールが登録されている。
Lifecycle 説明 process-resources resources:resources compile compiler:compile process-test-resources resources:testResources test-compile compiler:testCompile test surefire:test
参考 Built-in Lifecycle Bindings
例えば、「mvn test」を実行したら「mvn surefire:test」が実行されることになる。
注意点
フェーズは、指定されたフェーズまでの各フェーズも実行される。したがって、「mvn test」=「mvn surefire:test」ではなく、「mvn test」∋「mvn surefire:test」。
ライフサイクルとは?
ライフサイクルは、フェーズをグループとしてまとめたもの。
デフォルトは以下の3つ。
- default Lifecycle
- clean Lifecycle
- site Lifecycle
参考 Introduction to the Build Lifecycle
Tips
pluginのprefix
prefix:goal
のprefixには、以下のルールがある。
- maven-${prefix}-plugin
- ${prefix}-maven-plugin
参考 Specifying a Plugin’s Prefix
pluginのgoal
prefix:goal
のgoalは、helpゴールを利用すると一覧が表示できる。
$ mvn echo:help
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building sample 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- echo-maven-plugin:0.3.0:help (default-cli) @ sample ---
[INFO] Maven Echo Plugin 0.3.0
The Echo Maven Plugin is intended to print out messages during the build.
This plugin has 3 goals:
echo:echo
echo:format
echo:help
Display help information on echo-maven-plugin.
Call mvn echo:help -Ddetail=true -Dgoal=<goal-name> to display parameter
details.
...
参考 Maven で Plugin の usage を確認する
各フェーズのpluginを調べる
実効pomを表示すれば、各フェーズで実行されるpluginが調べられる。
$ mvn help:effective-pom
...
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<executions>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
...
フェーズにpluginのゴールを登録する
<executions>
タグ内で<phase>
と<goal>
を定義する。 たいていはpluginのサイトに例が載っているのでそれを参考にしたほうが良い。
<build>
<plugins>
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>echo-maven-plugin</artifactId>
<version>0.3.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>echo</goal>
</goals>
</execution>
</executions>
<configuration>
<echos>
<echo>This is the Test Text </echo>
</echos>
</configuration>
</plugin>
</plugins>
</build>
</project>
参考 Plugins
フェーズをスキップする
フェーズはスキップできない。ただし、フェーズに登録されたpluginをスキップする方法は、各pluginごとに用意されている。例えば、surefire:testだと-Dmaven.test.skip=true
や-DskipTests=true
。 install:installだと-Dmaven.install.skip=true
。
試しにsurefire:testをスキップするコマンドを打つと、testフェーズに登録していたecho-maven-pluginが動いてしまう。
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example.com</groupId>
<artifactId>sample</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>sample</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>echo-maven-plugin</artifactId>
<version>0.3.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>echo</goal>
</goals>
</execution>
</executions>
<configuration>
<echos>
<echo>This is the Test Text </echo>
</echos>
</configuration>
</plugin>
</plugins>
</build>
</project>
$ mvn clean package -Dmaven.test.skip=true
...
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ sample ---
[INFO] Not compiling test sources
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ sample ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- echo-maven-plugin:0.3.0:echo (default) @ sample ---
[INFO] This is the Test Text
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ sample ---
[INFO] Building jar: c:\Users\pbreh_000\Desktop\study\sample\target\sample-1.0-SNAPSHOT.jar
...
フェーズをスキップさせるのを疑似るなら、mavenのProfileを使えば良いっぽい。
参考 stack overflow