うさぎ好きエンジニアの備忘録

うさぎたちに日々癒されているエンジニアが業務で直面したもの & 個人的な学習メモを残していきます。

mvnを思い出す

最近触っていなかったらmvnコマンドの使い方をだいぶ忘れてしまったので思い出すために触り直す。

事前準備

Homebrewなどで事前にmavenをインストールしておく。

$ mvn -version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
...

使ってみる

archetypeでテンプレートを作成する

$ mvn archetype:generate -DgroupId=jp.co.kazono -DartifactId=sample

コマンドが成功すると以下のような構成でテンプレートが生成される。

$ tree .
.
└── sample
    ├── pom.xml
    └── src
        ├── main
        │   └── java
        │       └── jp
        │           └── co
        │               └── kazono
        │                   └── App.java
        └── test
            └── java
                └── jp
                    └── co
                        └── kazono
                            └── AppTest.java

javadocを生成する

$ mvn javadoc:javadoc

コマンドが成功するとtarget配下にjavadocが生成される。

siteでWebページを生成する

$ mvn site

コマンドが成功するとtarget/site配下にindex.htmlが生成される。

packageでパッケージを生成する

$ mvn package

コマンドが成功するとtargetディレクトリ が生成され、その配下に成果物が置かれている。

$ ls -l target
total 8
drwxr-xr-x  3 kazono  staff    96  2  1 21:44 classes
drwxr-xr-x  3 kazono  staff    96  2  1 21:44 generated-sources
drwxr-xr-x  3 kazono  staff    96  2  1 21:44 generated-test-sources
drwxr-xr-x  3 kazono  staff    96  2  1 21:44 maven-archiver
drwxr-xr-x  3 kazono  staff    96  2  1 21:44 maven-status
-rw-r--r--  1 kazono  staff  2667  2  1 21:44 sample-1.0-SNAPSHOT.jar
drwxr-xr-x  4 kazono  staff   128  2  1 21:44 surefire-reports
drwxr-xr-x  3 kazono  staff    96  2  1 21:44 test-classes

installで作成したパッケージをローカルリポジトリにインストールする

$ mvn install

コマンドが成功すると、他のプロジェクトからも参照することが可能になる。

exec:javaでメインクラスを指定して実行する

$ mvn exec:java -Dexec.mainClass=jp.co.kazono.App

実際に実行すると以下のような感じ。

$ mvn exec:java -Dexec.mainClass=jp.co.kazono.App
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------< jp.co.kazono:sample >-------------------------
[INFO] Building sample 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- exec-maven-plugin:3.0.0:java (default-cli) @ sample ---
Hello World!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.945 s
[INFO] Finished at: 2021-02-01T21:42:02+09:00
[INFO] ------------------------------------------------------------------------

ちなみに、事前にmvn installもしくはmvn packageしておかないと以下のようにエラーが起きるので注意。

java.lang.ClassNotFoundException: jp.co.kazono.App
    at java.net.URLClassLoader.findClass (URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:418)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:351)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:246)
    at java.lang.Thread.run (Thread.java:748)

classpathScopeを指定してexec:javaでクラスを実行する

src/test/java/jp/co/kazono配下にApp.javaCopiedApp.javaと名前を変更してコピーし、クラス名も変更して置いておく。

$ ls -l src/test/java/jp/co/kazono/CopiedApp.java
-rw-r--r--  1 kazono  staff  181  2  1 21:56 src/test/java/jp/co/kazono/CopiedApp.java
package jp.co.kazono;

/**
 * Hello world!
 *
 */
public class CopiedApp
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}

このCopiedAppを実行しようとする場合、何もオプションを指定せずにexec:javaを実行するとtestを見てくれず、コマンドが失敗してしまう。

$ mvn exec:java -Dexec.mainClass=jp.co.kazono.CopiedApp
...
java.lang.ClassNotFoundException: jp.co.kazono.CopiedApp
    at java.net.URLClassLoader.findClass (URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:418)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:351)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:246)
    at java.lang.Thread.run (Thread.java:748)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.929 s
[INFO] Finished at: 2021-02-01T22:01:10+09:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.0.0:java (default-cli) on project sample: An exception occured while executing the Java class. jp.co.kazono.CopiedApp -> [Help 1]

こういうケースの場合、-Dexec.classpathScopeで実行するクラスのスコープを変更してあげれば良い。

$ mvn exec:java -Dexec.mainClass=jp.co.kazono.AppTest -Dexec.classpathScope=test

testでテストコードを実行する

$ mvn test

実行すると以下のようにテストが実行される。

$ mvn test
...
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running jp.co.kazono.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.055 s - in jp.co.kazono.AppTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.083 s
[INFO] Finished at: 2021-02-01T21:49:33+09:00
[INFO] ------------------------------------------------------------------------

ちなみに-Dtestで実行したいテストのパッケージを指定することで、特定のテストのみを実行可能。

$ mvn test -Dtest=jp.co.kazono.AppTest

なお、クラス名が一意に特定できるのであればパッケージは省略してクラス名だけでも実行可能。

$ mvn test -Dtest=AppTest

cleanでtarget以下を削除する

$ mvn clean

コマンドが成功するとtarget以下が削除される。

$ mvn clean
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------< jp.co.kazono:sample >-------------------------
[INFO] Building sample 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ sample ---
[INFO] Deleting /Users/kazono/Workspaces/coding/java/sample/target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.382 s
[INFO] Finished at: 2021-02-01T21:47:02+09:00
[INFO] ------------------------------------------------------------------------