[ Topページへ戻る ]
2003.7.20よりアクセス
プログラムのコンパイル、JARファイル作成、ユニットテストのコンパイルと実行、ソースコード制御システム(CVS等)とのやり取り、ソースコードのチェッカによる検査、負荷テスト、などをコマンドライン環境で操作するのは非常に大変です。環境変数の設定、ツール毎のオプション指定を入力、プロジェクトごとのディレクトリ構成に応じたパス指定、などなど。
統合開発環境(Eclipse、NetBeans、JBuilderなど)を使うとコマンド環境を使う必要はなくなりますが、今度は作業の度に統合開発環境を立ち上げてプロジェクトを開いて実行するので、とっても面倒です。
例)プログラムが30本あるシステムの場合、30個のプロジェクトファイルそれぞれについて開いてはビルド実施、を繰り返す。
Antを使うと個々の作業を記述してコマンド一発で実行できるようになりますが、ビルドファイルの記述量も多くなります。大抵は雛型ビルドファイルを用意しておいて、コピー&修正で作ることになりますが、面倒です。
そんなときにMavenを使うと、このようなある程度定型化できそうな作業をツールでお膳立てしてくれるので、作業が楽になります。Mavenは内部的にはAntを呼び出しています(現バージョンでは)。
Mavenの視点は、ソフトウェアのライフサイクル作業(ビルド、リリース、配布、テスト実施とテストレポート生成、ドキュメント生成、依存ライブラリ管理)です。反復開発を行う場合、ライフサイクル作業を何度も繰り返し実行します。この作業を楽にしようというのが主眼にあって、個別の作業(例えばソースを書いてコンパイルするだけ)できめ細かいことをするのは別儀です。ライフサイクル作業全体を最適化するツールです。
Mavenは実のところ、とっつきの悪いツールです。Mavenのしきたりが分からないので、何をどうしていいのか所在がなく、しかも部分的に切り出して使うということも難しいからです。旅行先でバスに乗るときに、前扉からのるのか、後ろ扉からのるのか、料金は前払いなのか後払いか一定料金か距離で料金が変わるのか、ならば番号が押された紙片をのるときにどこかから取るのか、とかなり不安な気持ちになるのと似ています。
Maven 2.0が正式リリースされています。2.0系については、Maven 2.0ページをご覧ください。
まずはMavenを入手しましょう。MavenのホームページからDownloadのリンクをたどってmavenのアーカイブファイルをダウンロードします。2004年12月30日現在、以下のファイルが最新版です。
maven-1.0.2.exe maven-1.0.2.tar.bz2 maven-1.0.2.tar.gz maven-1.0.2.zip |
どこか適当な場所にアーカイブファイルを展開します。
次の環境変数を設定します。例は、C:\javaの下にmavenアーカイブファイルを展開した場合です。
JAVA_HOMEには使用するJDKのインストールディレクトリを指定しておきます。
環境変数名 | 設定例(OS:Windows) |
---|---|
MAVEN_HOME |
C:\java\maven-1.0-rc3 |
PATH |
%PATH%;%MAVEN_HOME%\bin |
JAVA_HOME |
C:\java\j2sdk1.4.2 |
動作検証中
Mavenはプロジェクトのビルドに必要な各種ライブラリを、ユーザ毎に固有のローカルリポジトリにダウンロードして利用します。最初にローカルリポジトリのディレクトリを設定します。
C:\home\torutk\work> echo %HOME% C:\home\torutk C:\home\torutk\work> install_repo.bat %HOME%\.maven\repository copying to repository C:\home\torutk\.maven\repository :(省略) C:\home\torutk\work> |
プロジェクト生成時には、上記設定に関わらず規定のディレクトリをリポジトリとして使用しているため、回避柵を以下に実施。但し成功していない。
このローカルリポジトリ設定で指定した場所は、プロパティ maven.repo.localに指定しておく必要があります。プロパティ指定を省略した場合、ローカルリポジトリのディレクトリとして、%HOMEDIRVE%\%HOMEPATH%\.maven\repository が適用されます。(Windows)
プロパティは、build.properitesまたはproject.propertiesファイルに指定します。マシン(ユーザ)共通で指定する場合、build.propertiesファイル中に指定します。build.propertiesファイルは、%HOMEDIRVE%\%HOMEPATH%\.maven\build.propertiesです。
maven.repo.local=C:/home/torutk/.maven/repository |
C:\home\torutk\work> maven -v __ __ | \/ |__ _Apache__ ___ | |\/| / _` \ V / -_) ' \ ~ intelligent projects ~ |_| |_\__,_|\_/\___|_||_| v. 1.0.2 C:\home\torutk\work> |
mavenは開発作業を行う際、標準ディレクトリ構成を持っています。これを変更することも可能ですが、労力が多いが益は少ないので、デフォルトの構成を使用します。デフォルト構成は、mavenコマンドに"genapp"というGoalを与えれば作成してくれます。
hello_maven +--- project.properties +--- project.xml +--- src +--- conf | +--- app.properties +--- java | +--- torutk | +--- hello | +--- App.java +--- test +--- torutk +--- hello +--- AbstractTestCase.java +--- AppTest.java +--- NaughtyTest.java |
ここで生成されたApp.javaは、"Hello World!"をプリントするクラスです。
mavenコマンドでgenappゴールをコマンドプロンプトで実行した例です。
C:\home\torutk>mkdir hello_maven C:\home\torutk>cd hello_maven C:\home\torutk\hello_maven>maven genapp __ __ | \/ |__ _Apache__ ___ | |\/| / _` \ V / -_) ' \ ~ intelligent projects ~ |_| |_\__,_|\_/\___|_||_| v. 1.0.2 Plugin cache will be regenerated ディレクトリ「C:\Documents and Settings\torutk\.maven\repository」は存在しません。 ディレクトリの作成を試みています。 「commons-jelly-tags-interaction-20030211.143817.jar」のダウンロードを試みていま す。 4K downloaded Enter a project template to use: [default] Please specify an id for your application: [app] Please specify a name for your application: [Example Application] Please specify the package for your application: [example.app] torutk.hello build:start: genapp: [copy] Copying 1 file to C:\home\torutk\hello_maven\src\java\torutk\hello [copy] Copying 3 files to C:\home\torutk\hello_maven\src\test\torutk\hello [copy] Copying 1 file to C:\home\torutk\hello_maven [copy] Copying 2 files to C:\home\torutk\hello_maven BUILD SUCCESSFUL Total time: 4 minutes 34 seconds Finished at: Fri Dec 31 03:51:04 JST 2004 C:\home\torutk\hello_maven> |
mavenにゴール"jar"を与えます。targetというディレクトリが生成され、その中にコンパイルしたクラスファイル、jarファイル、コンパイルされたテストクラスやテスト結果のファイルが生成されています。
hello_maven +--- maven.log +--- project.properties +--- project.xml +--- src | +--- conf | | +--- app.properties | +--- java | | +--- torutk | | +--- hello | | +--- App.java | +--- test | +--- torutk | +--- hello | +--- AbstractTestCase.java | +--- AppTest.java | +--- NaughtyTest.java +--- target +--- app-1.0.jar +--- classes | +--- torutk | +--- hello | +--- App.class +--- test-classes | +--- torutk | +--- hello | +--- AbstractTestCase.class | +--- AppTest.class | +--- NaughtyTest.class +--- test-reports +--- TEST-torutk.hello.AppTest.txt +--- TEST-torutk.hello.AppTest.html |
mavenコマンドでjarゴールをコマンドプロントで実行した例です。
C:\home\torutk\hello_maven>maven jar __ __ | \/ |__ _Apache__ ___ | |\/| / _` \ V / -_) ' \ ~ intelligent projects ~ |_| |_\__,_|\_/\___|_||_| v. 1.0-beta-10 「maven-SNAPSHOT.jar」のダウンロードを試みています。 .......... . 「commons-io-20030203.000550.jar」のダウンロードを試みています。 .. 「commons-net-1.0.0.jar」のダウンロードを試みています。 ........ . 「commons-httpclient-2.0-beta1.jar」のダウンロードを試みています。 ........ [中略] java:prepare-filesystem: [mkdir] Created dir: C:\home\torutk\javaw\hello_maven\target\classes java:compile: [echo] Compiling to C:\home\torutk\javaw\hello_maven/target/classes [javac] Compiling 1 source file to C:\home\torutk\javaw\hello_maven\target\classes java:jar-resources: [copy] Copying 1 file to C:\home\torutk\javaw\hello_maven\target\classes test:prepare-filesystem: [mkdir] Created dir: C:\home\torutk\javaw\hello_maven\target\test-classes [mkdir] Created dir: C:\home\torutk\javaw\hello_maven\target\test-reports test:test-resources: test:compile: [javac] Compiling 3 source files to C:\home\torutk\javaw\hello_maven\target\test-classes test:test: [junit] dir attribute ignored if running in the same VM [junit] Running torutk.hello.AppTest [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.171 sec jar:jar: [jar] Building jar: C:\home\torutk\javaw\hello_maven\target\app-1.0.jar BUILD SUCCESSFUL Total time: 1 minutes 46 seconds C:\home\torutk\hello_maven> |
注記1)最初のmavenの実行途中に、velocity-1.3.jarのダウンロード後例外(ClassNotFoundException: velociy)が発生しました。もう一回mavenを実行すると、ビルドが成功しました。原因は不明。
注記2)mavenや依存関係で指定したライブラリファイルをダウンロードして保持するローカルリポジトリの場所は、デフォルトでは${user.home}/.mavenディレクトリの中です。Windows 2000での典型的な場所は、C:\Documents and Setting\ユーザ名\.maven になります。ディレクトリを変更するには、プロパティmaven.repo.localで指定します。
mavenにゴール"dist"を与えます。ゴール"jar"でも生成されたtargetディレクトリの中に、app-1.0、distributions、docs、generated-xdocs、javadocというディレクトリが新たに生成されています。
app-1.0の中にはバイナリ配布用のディレクトリ構造binとソース配布用のディレクトリ構造srcがあります。
distributionsの中には、バイナリ配布用のアーカイブファイルとソース配布用のアーカイブファイル(それぞれzip形式とtar+gz形式)があります。
docsの中には、Javadocで生成されるドキュメントがあります。
hello_maven +--- maven.log +--- project.properties +--- project.xml +--- src | +--- conf | | +--- app.properties | +--- java | | +--- torutk | | +--- hello | | +--- App.java | +--- test | +--- torutk | +--- hello | +--- AbstractTestCase.java | +--- AppTest.java | +--- NaughtyTest.java +--- target +--- app-1.0.jar +--- app-1.0 | +--- bin | | +--- app-1.0 | | +--- app-1.0.jar | | +--- docs | | +--- apidocs | | +--- ... | +--- src | +--- build.xml | +--- project.properties | +--- project.xml | +--- app-1.0 | +--- src | +--- conf | | +--- app.properties | +--- java | | +--- ... | +--- test | +--- ... +--- classes | +--- torutk | +--- hello | +--- App.class +--- distributions | +--- app-1.0-src.tar.gz | +--- app-1.0-src.zip | +--- app-1.0.tar.gz | +--- app-1.0.zip +--- docs | +--- apidocs | +--- ... +--- generated-xdocs | +--- javadoc.xml +--- javadoc | +--- report.txt +--- test-classes | +--- torutk | +--- hello | +--- AbstractTestCase.class | +--- AppTest.class | +--- NaughtyTest.class +--- test-reports +--- TEST-torutk.hello.AppTest.txt +--- TEST-torutk.hello.AppTest.html |
ディレクトリ構造は人それぞれでしょうが、mavenを使用する場合はmavenのポリシーを知っておく必要があります。どうしても気に入らないようなら自分でプロジェクト設定をがりがりと記述すればよいと思いますが・・・。
上述でmavenにディレクトリを生成させると分かりますが、ソースファイル等はsrcの下に収められます。ソースファイル等は、設定ファイル、製品ソースファイル、テスト用ソースファイルの3つに分類されます。
src | conf | |
java | ||
test |
ソースファイルをビルドした結果はtargetの下に格納されます。ビルド結果は、製品クラスファイル、テスト用クラスファイル、テスト結果、製品JARファイルに分類されます。
target | app-1.0.jar | |
classes | ||
test-classes | ||
test-reports |
プロジェクトディレクトリの中に置いた以下のファイルは、リリース用アーカイブに自動的に含まれます。
LICENSE* README.txt |
J2EEアプリケーションは、EJBコンポーネントを収めるEAR、Webコンポーネントを収めるWAR、クライアントコンポーネントを収めるJARなどたくさんの生成物から構成されます。Mavenのプロジェクトは1つの生成物を構築するので、J2EEアプリケーションではMavenのプロジェクトを階層的に編成する必要があります。
以下、参考文献[c.]で紹介されているディレクトリ構成をベースに紹介します。
J2EEアプリケーション 基点ディレクトリ |
dev | modules | JARを作るサブプロジェクト |
WARを作るサブプロジェクト | |||
EJB-JARを作るサブプロジェクト | |||
applications | EARを作るサブプロジェクト | ||
containers | |||
nodes | |||
: | |||
設計情報 | |||
ドキュメント | |||
: |
これは、上述の「通常のアプリケーション」と同じ構成です。
Javaのソースコードの他、JSPファイル、HTMLファイル等のWebリソース、web.xml等の設定ファイルがあります。
ソースファイル等はsrcの下に収められます。ソースファイル等は、設定ファイル、製品ソースファイル、テスト用ソースファイルの3つに分類されます。genappで生成されるディレクトリ構成とはちょっと変えているので、一から作るかgenappで生成されるディレクトリを修正し、合わせてプロジェクト設定ファイルも修正するかどちらかの方法で作成します。
src | java | |||
test | ||||
webapp | WEB-INF | web.xml | ||
index.html | HTMLファイル等 |
webappディレクトリは、Mavenのプロパティ maven.war.srcのデフォルト値です。別な名前や場所に変更する場合は、プロパティmaven.war.srcを明示的に指定します。
ソースファイルをビルドした結果はtargetの下に格納されます。ビルド結果は、製品クラスファイル、テスト用クラスファイル、テスト結果、製品JARファイルに分類されます。
target | app-1.0.jar | |
classes | ||
test-classes | ||
test-reports |
mavenは、いくつかの定義済みのゴールを持っており、mavenコマンドでゴールを指定することによってゴールを達成するために必要な作業を開始します。
maven -g を実行します。
以下に主要なゴールとその内容を一覧表にして示します。(試してみたものだけ)
mavenゴール | 内容 |
---|---|
genapp | 新規にプロジェクトツリーを作成する |
jar | jar:jarの省略形。プロジェクトのソースをコンパイルしてJARファイルを生成 |
clean | clean:cleanの省略形。 |
ant | ant:generate-buildの省略形。Ant用build.xmlファイルの生成 |
jdee | Emacs JDEE用プロジェクトファイルの生成 |
dist | 配布用のバイナリパッケージ、ソースパッケージを作成する |
dist:build-bin | 配布用のバイナリパッケージを作成する |
dist:prepare-bin-filesystem | 配布用のバイナリパッケージのディレクトリツリーを作成する |
test | testディレクトリにあるJUnitテストケースを実行する(テキストモード) |
test:ui | JUnitのSwing版TestRunnerを起動する |
java:compile | コンパイル実施 |
java:jar-resources | src/confの中の*.propertiesファイルをtarget/classesの中にコピーする |
自分でproject.xmlをいじるためのメモ。
project | ||||
id | プロジェクトID文字列。生成するjarファイル名にも使用 | |||
name | 簡単な説明を兼ねたプロジェクトの名称 | |||
currentVersion | バージョン番号。生成するjarファイル名にも使用 | |||
build | ||||
sourceDirectory | Javaソースディレクトリの定義 | |||
unitTestSourceDirectory | ユニットテストのソースディレクトリの定義 | |||
unitTest | ||||
resources | ||||
reports | ||||
report |
build - resources の記述を見ると、
<resources> <resource> <directory>src/conf</directory> <includes> <include>*.properties</include> </includes> </resource> </resources>
となっている。src/confの直下にあるpropertiesファイルしかコピーされない。以下のように修正すると、src/confのサブディレクトリを対象とする。
<include>**/*.properties</include>
自分でproject.propertiesをいじるためのメモ。
プロパティ名 | 値の例 | 内容 |
---|---|---|
maven.compile.aspects | AspectJのアスペクトを組み込むかどうか | |
maven.compile.compilerargs | javacコンパイラへ渡す引数 | |
maven.compile.debug | on | javacの-gオプション |
maven.compile.deprecation | off | javacの-deprecationオプション |
maven.compile.encoding | javacの-encodingオプション | |
maven.compile.executable | javaコンパイラの実行名 | |
maven.compile.fork | javacを別プロセスで実行するか否か | |
maven.compile.optimize | off | 最適化コンパイルの有無 |
maven.compile.source | 1.4 | javacコンパイラの-sourceオプション |
maven.compile.src.set | ソースディレクトリ | |
maven.compile.target | 1.4 | javacの-targetオプション |
maven.compile.verbose | javacの-verboseオプション | |
maven.jar.mainclass | jp.gr.java_conf.torutk.Hello | JARファイルのMailClass:に実行クラス名を記述する |
maven.build.dest | ||
maven.build.dir | target | 作業成果物を置くディレクトリ |
maven.build.src | ||
maven.conf.dir | ||
maven.docs.dest | ||
maven.docs.outputencoding | ||
maven.docs.src | ||
maven.src.dir | ||
maven.proxy.host | ファイヤーウォール越えProxyサーバのホスト名 | |
maven.proxy.port | Proxyサーバのポート番号 | |
maven.proxy.username | Proxyサーバ認証用ユーザ名 | |
maven.proxy.password | Proxyサーバ認証用パスワード |
あらかじめ用意されているゴールを拡張したり、自分で定義するときは、プロジェクトのディレクトリにこのファイルを作成します。maven genappでは生成されないので、必要になった時点で新規にファイルを作成します。goalは新たにゴールを作成するときに使用します。preGoalとpostGoalは、既存のゴールを拡張するときに使用します。前者は既存のゴールを実行する前にフックされ、後者は既存のゴールを実行後にフックされます。
<?xml version="1.0" encoding="Shift_JIS"?> <project xmlns:j="jelly:core"> <goal name=...> ... </goal> <preGoal name=...> ... </preGoal> <postGoal name=...> ... </postGoal> </project> |
mavenの標準プラグインdistを拡張してみます。distで生成されるバイナリ配布用パッケージファイルの中に、binディレクトリを追加してその中に実行ファイルをいくつか置きたいとします。
まず、プロジェクトの直下にbinディレクトリがあり、この中にあるファイルをバイナリ配布用パッケージファイルの中にコピーするものとします。
<?xml version="1.0" encoding="Shift_JIS"?> <project xmlns:j="jelly:core"> <preGoal name="dist:build-bin"> <echo>preGoal of dist:build-bin</echo> <attainGoal name="dist:prepare-bin-filesystem"/> <mkdir dir="${maven.dist.bin.assembly.dir}/bin"/> <copy toDir="${maven.dist.bin.assembly.dir}/bin"> <fileset dir="${basedir}/bin"/> </copy> </preGoal> <postGoal name="dist:build-bin"> <echo>postGoal of dist:build-bin</echo> </postGoal> </project> |
まず、バイナリ配布用パッケージを作成するゴールが"dist:build-bin"なので、このpreGoalとpostGoalを作成することで拡張ができることが分かります。
今回は、dist:build-binの中でアーカイブファイルを作成するときには既にbin以下のファイルがアーカイブ作成用ディレクトリ下にコピー済みでないと目的を達成できないので、preGoalを使用します。
preGoalはゴールdist:build-binに対して定義するので、name属性はdist:build-binになります。
echo要素は単に実行時にメッセージを表示するためのものです。
コピー先にはあらかじめディレクトリツリーが作成されていなくてはなりません。dist:build-binの中で
プロパティのメモ(distプラグインで定義されているもの)
${maven.build.dir} ---> target
${maven.dist.dir} = ${maven.build.dir}/distributions
---> target/distributions
${maven.dist.assembly.dir} = ${maven.build.dir}/${maven.final.name}
---> target/app-1.0
${maven.dist.bin.assembly.dir} = ${maven.dist.assembly.dir}/bin/${maven.final.name}
---> target/app-1.0/bin/app-1.0
Mavenのプロジェクトは、たった一つの成果物(例:jarファイル)を構築するために使用します。複数の成果物を構築する、例えばJ2EEプロジェクト(EARファイルにはWARファイルが含まれているため、複数の成果物が存在)での例を考えます。
Firewall内等でプロキシーサーバーを経由する必要がある場合の設定です。
以下のプロパティを設定します。設定するファイルは、お勧めとしては${user.home}/build.propertiesです。
Windows 2000/XP系のOSでは、${user.home} は、C:\Documents and Setting\foo などになります。確認方法の例は以下。
System.out.println(System.getProperty("user.home"));
プロキシーサーバがproxy.mydomain:8080の場合の例。usernameとpasswordはプロキシーサーバーがユーザー認証を必要とする場合に記述します。
maven.proxy.host=proxy.mydomain maven.proxy.port=8080 maven.proxy.username=foo maven.proxy.password=bar |
デフォルトの設定でJARファイルを生成すると、Manifestファイルには以下の情報が記載されます。
Manifest-Version: 1.0 Ant-Version: Apache Ant 1.5.3 Created-By: Apache Jakarta Maven Built-By: toru Package: helloagain.kanday Build-Jdk: 1.5.0-beta3 Extension-Name: kanday Specification-Title: How to program java desktop application Specification-Vendor: TAKAHASHI,Toru Implementation-Title: helloagain.kanday Implementation-Vendor: TAKAHASHI,Toru Implementation-Version: 1.0.1 |
Ant-VersionとCreate-Byは固定(前者は不明、後者はmaven-jar-pluginのplugin.jellyの中にハードコード)
Built-By は、ログインしているユーザ名(Maven実行時の${user.name})が入ります。
Packageは、project.xmlのpackage要素が入ります。
Build-Jdkは、実行しているJDKバージョン(Maven実行時の${java.version})が入ります。
Extension-Nameは、project.xmlのid要素が入ります。
Specification-Titleは、project.xmlのshortDescription要素が入ります。
Specification-VendorおよびImplementation-Vendorは、project.xmlのorganization要素の子要素nameが入ります。
Implementation-Titleは、project.xmlのpackage要素が入ります。
Implementation-Versionは、project.xmlのcurrentVersion要素が入ります。
ここでSpecification-Versionが設定されていないのですが、これはmaven-jar-plugin-1.5のplugin.jellyのなかでコメントアウトされているからです。