仕事でHudsonを導入したいと思っているのですが、Meven2と組み合わせた方がいろいろできるらしいので、Maven2について調べてみました。
半日くらいさわった後でのMaven2の印象
- いまどきコマンドラインベース
- Eclipseとそんなに相性が良くない(Eclipseのプラグインが微妙)
- Antと比べて挙動が見えない
- XMLの記述量が多い
- 用語が多い
- 最初の壁を越えると意外と簡単
- 継続的インテグレーションをやる場合、Antより楽そうに思える
- 嫌でも開発プロセスが確立される
Mavenは1の頃にさわってみて、Antに逃げ帰った思い出があるので、そもそも悪い印象が多いのですが、そこは我慢してHudsonを使った運用を確立させるために頑張ってみます。
pom.xml
まずこのxmlが問題なわけです。
Mavenサイトに全体の構成が載っていますが、まずこれで使うのを止めたくなるわけです。
もう、どんな嫌がらせだよ、と。
と、思っていたのですが、単純な構成だと実はそんなに使う項目が多くなかったりします。
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"> <!-- プロジェクト設定 --> <build> <!-- 入出力の設定 --> <plugins> <plugin> <!-- ビルド設定 --> </plugin> </plugins> </build> <reporting> <plugin> <!-- レポート設定 --> </plugin> </reporting> <dependencies> <dependency> <!-- ライブラリ依存関係の設定 --> </dependency> </dependencies> </project>
コメントで書かれたところには、それぞれの子要素が入るので、そのまま実行できるわけではないのですが、こう見るとそんなに項目が多くないことがわかると思います。
以下、1つずつ追っていきます。
プロジェクト設定
<groupId>jp.tanamon</groupId> <artifactId>mvntest</artifactId> <packaging>war</packaging> <version>1.0.0</version> <name>${project.artifactId}</name> <url>http://tanamon.jp/${project.artifactId}/</url>
groupId
組織としてユニークであればいいので、Javaのパッケージ名と同じにしておくとわかりやすいです。
artifactId
プロダクトごとにユニークであればいいので、Eclipseのプロジェクト名あたりと同じにしておくとわかりやすいです。
version
プログラムの変更ごとにユニークになるものだと思います。ナンバリングルールは社内でルール決めをすればよいです。しかし、実際の開発ではここに書かれていると管理が不便な気がするのですが、どう解決すべきかはそのうち調べます。
name
レポート等に出る表示名称です。artifactIdがapp0001みたいな名前にしなきゃいけないような不思議な組織がたまにあるので、そういった場合に表示名を別途指定できます。例では変数を使ってartifactIdと同じにしていますが、普通はこれでよいように思えます。
url
サイトのURLです。入口が複数ある場合はどうするんでしょうかね?
入出力設定
<finalName>${project.artifactId}-${project.version}</finalName> <sourceDirectory>src/main/java</sourceDirectory> <outputDirectory>target/classes</outputDirectory> <testSourceDirectory>src/test/java</testSourceDirectory> <testOutputDirectory>target/test-classes</testOutputDirectory> <resources> <resource> <directory>src/main/resources</directory> </resource> </resources> <testResources> <testResource> <directory>src/test/resources</directory> </testResource> </testResources>
これらの設定値はデフォルト値です。Maven2推奨の構成らしいですが、特にディレクトリ構成など、この構成だとどう嬉しいのかそのうち調べます。
まぁ、最初は従っていたほうが余計な現象に悩まされなくていいと思います。
ビルド設定
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin>
Maven2は大抵の機能がプラグインによって実装されているため、ほとんどの場合、Maven2の機能を使うということはプラグインを追加する、ということになります。
また、ビルド設定とレポート設定(後述)は対になっているものが多いです。
ここではビルド時に使用するプラグインを指定します。
よく使われるプラグインはAvailable Pluginsに一覧があります。
各プラグインページのUsageのhereリンクの先に、使い方が載っています。
英語ですが、同じテンプレートで書かれているので、何とか読めると思います。
ちなみに、上記例はCompiler Pluginの設定になります。JDKのバージョンを指定できるものなので、大抵の開発で使うプラグインだと思います。
レポート設定
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <configuration> <docencoding>UTF-8</docencoding> <charset>UTF-8</charset> <encoding>MS932</encoding> <bottom></bottom> </configuration> </plugin>
こちらの設定もプラグインによって異なりますが、記述は大体一緒です。ここでは、レポート作成時に使用するプラグインを指定します。
上記例は、Javadoc Pluginの設定になります。
また、ウチの会社では残念なことにJavaソースがUTF-8化されていないので、文字コードをMS932にしています。
ライブラリ依存関係の設定
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency>
ライブラリの依存関係を明示的に指定できます。
ここに記述することで、たとえばUnitTest時にしか使用しないようなライブラリを除いたりすることができます。
とはいえ、ライブラリごとにgroupIdとartifactIdが違うため、Maven Repositoryから定義を探してきます。
上記例ではjunit 3.8.1のPOM Dependencyの記述からテンプレートが探せます。
version
versionは記述しないと、自動的に最新版を取得してきます。また、範囲指定をすることでマイナーバージョンアップの範囲でバージョンアップする、という指定もできます。
が、普通の開発では使わない気がします。
テスト後に勝手にバージョンアップされたら悲惨です。
基本は明示的にバージョン指定を行っておくものだと思います。
scope
この値でどのスコープでライブラリが必要かを指定します。
- compile 常にクラスパスに追加し、配布物に含める。デフォルト値。
- provided コンパイル時に必要な場合。配布物には含めない。Servlet APIなど。
- runtime コンパイル時に不要で、実行時に必要な場合。配布物には含めない。JDBCドライバなど。
- test テスト実行時にクラスパスに追加する。JUnitなど。
- system スコープとしてはcompileと同一。ローカルの別の場所にあるライブラリをsystemPathタグで明示的に指定する。
- import Maven2.0.9以降の新機能。dependencyManagementを使ってごにょごにょやるらしい。省略。
ここら辺は自身がないので間違っているかもしれないので、詳しくはDependency Scopeを参照のこと。
Maven Repositoryで見つからないライブラリ
DjUnit等のライブラリのように、Maven Repositoryに無いライブラリについては、以下のどちらかの対応をします。
ローカルリポジトリに入れる
mvnコマンドでライブラリを明示的に登録させます。
mvn install:install-file -Dfile=${JARファイルのパス} -DgroupId=${groupId} -DartifactId=${artifactId} -Dversion=0.8.3 -Dpackaging=jar -DgeneratePom=true
artifactIdとgroupIdの値はpom.xmlと一致させればいいので何でもよいですが、命名規則は合わせた方がよいと思います。
ちなみに、DjUnitを登録する時はこんなコマンドで登録しました。
mvn install:install-file \ -Dfile=C:\apache-maven-2.0.9\install-lib\djunit.jar \ -DgroupId=jp.co.dgic \ -DartifactId=djunit \ -Dversion=0.8.3 \ -Dpackaging=jar \ -DgeneratePom=true
最後に
エラーが発生した場合
mvnコマンドに-Xオプションを付けて実行するとデバッグモードになるので、わかるかもしれません。