マルチプロジェクトとは? †
- 複数の Mavenプロジェクト をまとめてビルドしたりテストしたりしたい
- たとえば Web アプリを作るときに、View層(Webプロジェクト) と Domain層(Jarプロジェクト)を分けて作りたいときがある
- アプリの規模が巨大でビルドに時間がかかるとか、View 層と Domain 層の関係を疎にしたいとか
- Jarプロジェクトには Unit テストを貼り付けて、単体でビルド・テストをできるようにしたい
- Webプロジェクトでは、Jarプロジェクトの成果物を WEB-INF/lib に 入れて参照する
- マルチプロジェクトにすると mvnコマンド一発で
- Jarプロジェクトをビルドし、
- できた JAR ファイルを Webプロジェクトにコピーして、
- Webプロジェクトをビルドして war ファイルを作る。
- ついでに、テストをしてテストレポートを作ったり、Javadocなんかもできちゃったり
マルチプロジェクトの作成 †
- 親プロジェクトの作成
[~/java]$ mvn archetype:generate -DartifactId=multi-prj -DgroupId=com.snail.exam
[追記] archetype:create は、Maven 3.0.5 で廃止。代わりに generate を使う
- 親プロジェクトの pom.xml の編集
[~/java]$ cd multi-prj
[~/java/multi-prj]$ vi pom.xml
<packaging> を jar から pom に変更して、マルチプロジェクトの親プロジェクトであることを宣言する
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.snail.exam</groupId>
<artifactId>multi-prj</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>multi-prj</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>
</project>
- 子プロジェクトの作成
[~/java/multi-prj]$ mvn archetype:generate -DartifactId=mulpro-jar -DgroupId=com.snail.exam
[~/java/multi-prj]$ mvn archetype:generate -DartifactId=mulpro-web
-DgroupId=com.snail.exam -DarchetypeArtifactId=maven-archetype-webapp
[追記] archetype:create は、Maven 3.0.5 で廃止。代わりに generate を使う
- Jar プロジェクトと Web プロジェクトの関連づけ
[~/java/multi-prj]$ cd mulpro-web
[~/java/multi-prj/mulpro-web]$ vi pom.xml
mulpro-jar を <dependency> に追加する
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>multi-prj</artifactId>
<groupId>com.snail.exam</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.snail.exam</groupId>
<artifactId>mulpro-web</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>mulpro-web Maven Webapp</name>
<url>http://maven.apache.org</url>
<build>
<finalName>mulpro-web</finalName>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.snail.exam</groupId>
<artifactId>mulpro-jar</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
で、どういうモノができたのか? †
[~/java/multi-prj]$ tree
.
|-- mulpro-jar
| |-- pom.xml
| |-- src
| | |-- main
| | | `-- java
| | | `-- com
| | | `-- snail
| | | `-- exam
| | | `-- App.java
| | `-- test
| | `-- java
| | `-- com
| | `-- snail
| | `-- exam
| | `-- AppTest.java
| `-- target
| |-- classes
| | `-- com
| | `-- snail
| | `-- exam
| | `-- App.class
| |-- maven-archiver
| | `-- pom.properties
| |-- mulpro-jar-1.0-SNAPSHOT.jar
| |-- surefire-reports
| | |-- TEST-com.snail.exam.AppTest.xml
| | `-- com.snail.exam.AppTest.txt
| `-- test-classes
| `-- com
| `-- snail
| `-- exam
| `-- AppTest.class
|-- mulpro-web
| |-- pom.xml
| |-- src
| | `-- main
| | |-- resources
| | `-- webapp
| | |-- WEB-INF
| | | `-- web.xml
| | `-- index.jsp
| `-- target
| |-- classes
| |-- maven-archiver
| | `-- pom.properties
| |-- mulpro-web
| | |-- META-INF
| | |-- WEB-INF
| | | |-- classes
| | | `-- web.xml
| | `-- index.jsp
| |-- mulpro-web.war
| `-- war
| `-- work
| `-- webapp-cache.xml
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- com
| `-- snail
| `-- exam
| `-- App.java
`-- test
`-- java
`-- com
`-- snail
`-- exam
`-- AppTest.java
49 directories, 20 files
[~/java/multi-prj]$
親プロジェクトの 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.snail.exam</groupId>
<artifactId>multi-prj</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>multi-prj</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>
<modules>
<module>mulpro-jar</module>
<module>mulpro-web</module>
</modules>
</project>
子 Web プロジェクトの pom.xml †
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>multi-prj</artifactId>
<groupId>com.snail.exam</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.snail.exam</groupId>
<artifactId>mulpro-web</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>mulpro-web Maven Webapp</name>
<url>http://maven.apache.org</url>
<build>
<finalName>mulpro-web</finalName>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.snail.exam</groupId>
<artifactId>mulpro-jar</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
子 Jar プロジェクトの pom.xml †
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>multi-prj</artifactId>
<groupId>com.snail.exam</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.snail.exam</groupId>
<artifactId>mulpro-jar</artifactId>
<version>1.0-SNAPSHOT</version>
<name>mulpro-jar</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>
</project>
Eclipseへのインポート †
マルチプロジェクトを Eclipse にインポートする †
- [ファイル]-[インポート]
- 親プロジェクトと2つの子プロジェクトをインポートする
依存ライブラリの定義 †
- 親プロジェクト( multi-prj )の pom.xml に、log4j を追加すると、子プロジェクトの mulpro-jar、mulpro-web にも log4j が追加されている。
- また、mulpro-web の依存ライブラリに mulpro-jar が追加されていることが分かる。
ビルドとテスト †
mvn コマンドではもちろんビルドは上手くいく †
m2eclipse 付属の 組み込み版 Maven 2 ではマルチプロジェクトをビルドできない †
- m2eclipse 付属の embedded maven ではマルチプロジェクトのビルドが途中で止まってしまう
m2eclipse 0.9系統 の Embedded Maven 2.0 でも 0.10系統の Embedded Maven 3.0 でもダメ
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.356s
[INFO] Finished at: Thu Mar 04 02:00:54 JST 2010
[INFO] Final Memory: 10M/79M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.0.2:compile
(default-compile) on project mulpro-jar: Compilation failure
Failure executing javac, but could not parse the error:
エラー:/Users/kagyuu/.m2/repository/javax/jms/jms/1.1/jms-1.1.jar の読み込みエラーです。cannot read zip file
エラー 1 個
-> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <goals> -rf :mulpro-jar
m2eclipse のビルドエンジンを 通常の Maven 2 に変更する †
- Mac を使っている人は一手間必要
- [Eclipse]-[環境設定]-[Maven]-[インストール] で、通常の Maven 2 をビルドエンジンに指定する
- 後は、プロジェクトを右クリックして実行すれば、Mavne 2 が走る
[追記] 親プロジェクトからまとめて mvn cobertura:cobertura する場合の工夫 †
- ☆ Jenkins は、マルチプロジェクトの親プロジェクトで test すると、子プロジェクトを全部 test して集計してくれる
- checkstyle や findbugs は、子プロジェクトに定義しておくだけで、子プロジェクトの test フェーズに実行してくれる
- でも cobertura だけ動かない... cobertura は、test フェーズの前に実行してやる必要が有るため
- そんならと親プロジェクトで mvn cobertura:cobertura すると cobertura なんて知らねぇよと言われる
マルチプロジェクトの site †
Maven Site
Java Maven