Mavenのマルチモジュール

今回、初めてMavenのマルチモジュールを体験しました。マルチモジュールにしたい理由は色々あるとは思うけど、今回遭遇したのは携帯アプリ作成時の話。

アプリのプロダクトコードにはJ2MEの制限されたJDKを使う必要があるけど、テストコードにはJDK1.6とかJUnit4とかを使ってさくさくテストコードを書きたい。けれど、同じプロジェクトに入れておくと同一のJDKを使用する必要がある*1。というわけで、プロダクトコードとテストコードを別個に分けました。

Parent
  |-- App
  |    |-- pom.xml
  |
  |-- Test
  |    |-- pom.xml
  |
  |-- pom.xml


Maven マルチモジュール・プロジェクト -TECHSCORE-を参照すれば、基本的な設定はできるかと思います。ここでは、マルチモジュールで実際に開発を進めていくときに個人的に詰まったところを中心に。

マルチモジュールをEclipseでインポート

このやり方、言われてみれば当たり前ですが思いつきませんでした><

  1. Parentモジュールからチェックアウト
  2. Parentモジュールのディレクトリで、[mvn eclipse:eclipse]
    • POMに子モジュール用のが設定されていれば、子モジュール用の.projectなども一緒に作成される
  3. [ファイル > インポート > 一般 > 既存プロジェクトをワークスペースへ]で、App, Testモジュールをそれぞれインポート

あとは、モジュール全体を一括でコミット/更新したい場合は親モジュール上で、それぞれ別個に操作したい場合は各モジュール上で行いましょう。

SNAPSHOTバージョンでローカルリポジトリを参照

TestモジュールからAppモジュールを参照する際、Appをローカルリポジトリにインストールしてリポジトリ経由で参照するようにしています。ただ、Eclipse上での開発(mvn eclipse:eclipse)では、SNAPSHOTバージョンではEclipseのプロジェクトを直接参照するようになっています。

Appモジュールの修正が直接Testモジュールに反映されるのは楽なのですが、これだとEclipseとそれ以外の環境で異なっているので問題が起きる場合もあります*2

これは、maven-eclipse-pluginの下記の設定で制御できるようです。(⇒
eclipse:eclipse

<useProjectReferences>false</useProjectReferences>

そもそもマルチモジュールに分けたなら、Eclipseのプロジェクト参照するのは筋が違うって話なのかもですね。プロジェクト参照を使いたいなら、同じプロジェクトに入れろってことで。

マルチモジュールをHudsonでビルド

これはMavenというよりHudson関連ですが。今は以下のようにHudsonを設定しています。

  • Mavenのモジュールが分かれている場合、モジュールごとにHudsonのジョブ作成
  • Mavenのプロファイルが複数用意されている*3場合、プロファイル数分だけ同一ジョブ内でビルド

Hudsonでジョブを分けるとジョブごとにワークスペースも分かれるので、モジュール間参照が難しくなるのですよね。ここは前述したとおり"mvn install"でローカルリポジトリにインストールして、そこを参照するようにしています。


アプリケーションを適切にマルチモジュール化できると、問題の切り分けやモジュールの再利用がやりやすくなります。この辺のノウハウは実際に試行錯誤する中で身につくものと思っているので、この機会に色々吸収してブログでもアウトプットする中で再度確認しながら身に付けて行きたいです。

*1:ですよね?ちょっと試してたのですが、src/mainとsrc/testでJDKを分ける方法がないように思えたので…

*2:はい、Eclipseでビルド通ったのにコミット後のHudson上でビルド失敗したってのが何回かありました

*3:微妙に異なるアプリを作成するために、プロファイルを分けています。例えば、特別なライブラリを含むアプリと含まないアプリ(該当部分はダミーのコードを入れておく)を作ったり。