7. Maven Tips
2006.08.04 株式会社四次元データ 鈴木 圭
- 7.1. 標準のディレクトリ構成
- 7.2. プロジェクトのライフサイクルにおける各フェイズ
- 7.3. フェイズとゴール
- 7.4. 複数のゴールやフェイズを一度に実行できる
- 7.5. デフォルト設定を含めた pom.xml や setting.xml の情報を得る
- 7.6. Ant 用のビルドファイル (build.xml) を生成する
- 7.7. コンパイルするソースコードのバージョンを指定する
- 7.8. 生成する javadoc の設定を行う
- 7.9. ライブラリをローカルリポジトリにインストールする
- 7.10. Sun の JAR ファイルをリポジトリに登録する場合の注意
- 7.11. 依存ライブラリを指定ディレクトリにコピーする
- 7.12. 配布用のアーカイブ (zip や tar.gz など) を作成する
- 7.13. Eclipse と併用しているときの注意
- 7.14. 作成しているプロジェクトの特定のクラスを実行する
- 7.15. マルチモジュール・プロジェクトの作成
- 7.16. 独自の Archetype の作成
- 7.17. native2ascii を実行する
- 7.18. Ant タスクの実行方法
- 7.19. プラグインを特定のフェイズで実行する
7.11. 依存ライブラリを指定ディレクトリにコピーする
依存するライブラリを特定のディレクトリにコピーするには、dependency-maven-plugin を使用します。
依存するライブラリを取得するには以下のコマンドを実行します:
mvn dependency:copy-dependencies
この場合、デフォルトの出力先である target/dependency ディレクトリに出力されます。
コピー先ディレクトリを指定するには outputDirectory 引数で指定します。例えば、依存ライブラリを lib ディレクトリにコピーするには次のようにします:
mvn dependency:copy-dependencies -DoutputDirectory=lib
dependency-maven-plugin のさらに詳しい情報は、dependency-maven-plugin のサイトを参照してください。
7.12. 配布用のアーカイブ (zip や tar.gz など) を作成する
配布用のアーカイブを作成するには、maven-assembly-plugin を使用します。
maven-assembly-plugin ではアセンブリ記述子 (assembly descriptor) によって、作成するアーカイブに含めるファイルや出力ファイル名の指定を行います。アセンブリ記述子は独自に作成するか、デフォルトで定義されているものを利用します。
デフォルトで定義されているアセンブリ記述子は 3 つあり、「bin」、「jar-with-dependencies」、「src」という ID で参照することができます。それぞれの意味は次の通りです:
bin | バイナリ配布用のアーカイブを作成します。アーカイブにはプロジェクトの成果物と README やライセンス・ファイルが含められます (依存するライブラリは含められません)。 |
jar-with-dependencies | プロジェクトと依存するライブラリをまとめた 1 つの JAR ファイルを作成します。 |
src | ソース配布用のアーカイブを作成します。 |
7.12.1. デフォルトのアセンブリ記述子を利用する
まずはデフォルトで定義されているアセンブリ記述子を利用してみましょう。バイナリ配布用のアーカイブを作成するには、次のコマンドを実行します:
mvn assembly:assembly -DdescriptorId=bin
これを実行すると、target ディレクトリに配布用のアーカイブが 3 種類 (zip, tar.bz2, tar.gz 形式) 作成されます。
7.12.2. 独自のアセンブリ記述子を使用する
次は独自のアセンブリ記述子を作成して、それを利用してみましょう。
Maven の標準ディレクトリ構成では、src/main/assembly ディレクトリにアセンブリ記述子を配置することになっています。今回は、実行に必要なファイルを zip 形式で出力するためのアセンブリ記述子を作成したいと思います。アセンブリ記述子は src/main/assembly/executable.xml として次の内容で作成します:
<assembly> <id>executable</id> <formats> <format>zip</format> </formats> <fileSets> <fileSet> <directory>target</directory> <outputDirectory>/</outputDirectory> <includes> <include>*.jar</include> </includes> </fileSet> </fileSets> <dependencySets> <dependencySet> <unpack>false</unpack> <scope>runtime</scope> <outputDirectory>/</outputDirectory> </dependencySet> </dependencySets> </assembly>
maven-assembly-plugin のサイトにおけるアセンブリ記述子の書式に関するドキュメンテーションが不十分なため、分からない部分については実際に試した結果に基づき説明します。
まず、全体は assembly 要素で囲みます。assembly 要素の中には、id (適当な識別子) と formats (出力する形式)、fileSets (アセンブリに含めるファイル)、dependencySets (アセンブリに含める依存ライブラリ) などを含めることができます。
id 要素には、そのアセンブリ記述子を識別するための適当な値を指定します。この値は、出力されるアセンブリの名前の一部に使用されるようです。
formats 要素には、入れ子にした format 要素により、出力するアセンブリの形式を指定します。format 要素で指定できる値についてのドキュメンテーションは見つからなかったのですが、「dir」「jar」「zip」「tar」「tar.gz」「tar.bz2」を指定できることを確認しました。
fileSets 要素には、入れ子にした fileSet 要素によりアセンブリに含めるファイルを指定します。fileSet 要素の中には、directory (アセンブリに含めるディレクトリ) や outputDirectory (出力するアセンブリの中でのパス)、includes (含めるファイルのパターン)、excludes (除外するファイルのパターン) などを指定することができます。outputDirectory に「/abc/def」という値を指定すると、その fileSet で指定されたファイルは、出力されたアセンブリを展開したディレクトリから見て、/abc/def ディレクトリに配置されます。
dependencySets 要素には、入れ子にした dependencySet 要素により、プロジェクトの依存するライブラリの中からどれをアセンブリに含めるかを指定します。dependencySet 要素の中には、unpack や scope (どのスコープのライブラリを含めるか)、outputDirectory (出力するアセンブリの中でのパス)、includes (含めるファイルのパターン)、excludes (除外するファイルのパターン) などを指定することができます。unpack に true を設定した場合、その dependencySet で指定されたライブラリ (JAR など) は、展開された形でアセンブリに含められます。
このアセンブリ記述子を使用してアセンブリを作成するには、先ほどとは異なり「descriptorId」ではなく「descriptor」引数で、作成したアセンブリ記述子のパスを与えます:
mvn assembly:assembly -Ddescriptor=src/main/assembly/executable.xml
7.12.3. pom.xml での設定
アセンブリを何度も作成する場合は、pom.xml に使用するアセンブリ記述子などの情報を記述しておいたほうが便利です。以下に設定例を示します:
<project ...> ... <build> ... <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptor>src\main\assembly\executable.xml</descriptor> </configuration> </plugin> ... </plugins> ... </build> ... </project>
pom.xml に使用するアセンブリ記述子の設定をしてしまえば、以下のコマンドでアセンブリを作成することができます:
mvn assembly:assembly
maven-assembly-plugin のさらに詳しい情報は、maven-assembly-plugin のサイトを参照してください。
7.13. Eclipse と併用しているときの注意
「mvn eclipse:eclipse」コマンドは、コマンドを実行した時点の pom.xml の内容に基づき .project や .classpath ファイルを作成します。そのため、pom.xml において依存するライブラリの追加/削除を行った場合は、再び「mvn eclipse:eclipse」コマンドを実行し、クラスパスの情報を更新しなければなりません。また、「mvn eclipse:eclipse」を実行した後は Eclipse 側でプロジェクトをリフレッシュして最新の情報を反映させます。
7.14. 作成しているプロジェクトの特定のクラスを実行する
Ant の Java タスクのように特定のクラスを実行するには、exec-maven-plugin を使用します。
exec-maven-plugin の設定示します:
<project ...> ... <build> ... <plugins> ... <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <configuration> <!-- 実行するクラス --> <mainClass>com.example.maven.sample.Main</mainClass> </configuration> </plugin> ... </plugins> ... </build> ... </project>
この例では、実行するクラスとして com.example.maven.sample.Main を指定しています。そして、実際に実行するには次のコマンドを使用します:
mvn exec:java
実行するクラスは「mvn exec:java」コマンドの引数でも指定することができます。その場合は pom.xml の <mainClass> 要素を削除しておきます:
mvn exec:java -Dexec.mainClass=<実行したいクラスの完全限定名>
exec-maven-plugin では Java のクラスだけではなく、通常の実行可能ファイルの実行も行うことができます。exec-maven-plugin のさらに詳しい情報は、exec-maven-plugin のサイトを参照してください。
7.15. マルチモジュール・プロジェクトの作成
マルチモジュール・プロジェクト (いくつかのサブプロジェクトから成るプロジェクト) を作成する方法を説明します。
例として「multimodule」という名前のマルチモジュール・プロジェクトを実際に作成しながら説明します。multimodule は「multimodule-common」と「multimodule-main」という 2 つのモジュールで構成されます。(「プロジェクト」と「モジュール」という言葉を使い分けていますが、単純に親となるプロジェクトを「プロジェクト」、子となるプロジェクトを「モジュール」と呼んでいるだけで、両者に本質的な違いはありません。)
それでは、親となる「multimodule」を作成します:
mvn archetype:create -DgroupId=com.example.multimodule -DartifactId=multimodule
作成された multimodule ディレクトリに移動し、multimodule-common と multimodule-main を作成します:
cd multimodule mvn archetype:create -DgroupId=com.example.multimodule.common -DartifactId=multimodule-common mvn archetype:create -DgroupId=com.example.multimodule.main -DartifactId=multimodule-main
次に、multimodule の pom.xml を修正します。修正点は <packaging> を pom に変更することと、<modules> 要素を追加し、サブモジュールを指定することです。また、<dependencies> 要素は不要なので削除します:
<project ...> <modelVersion>4.0.0</modelVersion> <groupId>com.example.multimodule</groupId> <artifactId>multimodule</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>multimodule-common</module> <module>multimodule-main</module> </modules> </project>
さらに multimodule-common と multimodule-main の pom.xml も修正します。 修正点は <parent> 要素を追加し、親となるプロジェクトを指定することです:
<project ...> ... <parent> <groupId>com.example.multimodule</groupId> <artifactId>multimodule</artifactId> <version>1.0-SNAPSHOT</version> </parent> ... </project>
これで、マルチモジュール・プロジェクトの作成ができました。例えば、全てのモジュールをコンパイルするには、multimodule ディレクトリで「mvn compile」コマンドを実行すれば、プロジェクトに含まれる全てのモジュール (multimodule-common および multimodule-main) のコンパイルが行われます。
ここで作成したプロジェクトは以下のリンクからダウンロードすることができます:
7.16. 独自の Archetype の作成
Maven ではプロジェクトのスケルトンとして、いくつかの Arcyetype が http://www.ibiblio.org/maven2/org/apache/maven/archetypes/ に用意されています。しかし、独自の Archetype を作成することもできます。
独自の Archetype を作成から使用までの手順は、最初に Archetype 用のプロジェクトを作成してから、それをリポジトリにインストールします。作成した Archetype をもとにプロジェクトを作成するには、通常通り「mvn archetype:create」コマンドで行います。
7.16.1. プロジェクトの全体像
http://www.ibiblio.org/maven2/org/apache/maven/archetypes/ を見ると、maven-archetype-archetype という Archetype があったので、これを使おうと思ったのですが、プロジェクトの作成に失敗してしまいました。そこで、プロジェクトは「mvn archetype:create -DgroupId=... -DartifactId=...」で作成したものを修正するか、全て手作業で作成する方法をとります。
ここでは、maven-archetype-sample という名前のプロジェクトとして、単純な Archetype を作成してみます。最終的なディレクトリ構成は以下のようになります:
maven-archetype-sample │ pom.xml │ └─src └─main └─resources ├─archetype-resources │ │ pom.xml │ │ │ └─src │ └─main │ └─java │ Sample.java │ └─META-INF archetype.xml
src/main/resources/META-INF/archetype.xml ファイルに Archetype の情報を記述します。また、src/main/resources/archetype-resources ディレクトリ以下に、プロジェクトのスケルトンを作成します。
7.16.2. プロジェクトの作成
プロジェクトを作成します。まず、maven-archetype-sample/pom.xml を以下のように作成します:
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.example.maven.archetype.sample</groupId> <artifactId>maven-archetype-sample</artifactId> <packaging>maven-plugin</packaging> <version>1.0</version> </project>
packaging 要素に「maven-plugin」を指定することに注意してください。
7.16.3. プロジェクトのスケルトンの作成
次にプロジェクトのスケルトンを src/main/resources/archetype-resources ディレクトリ以下に作成します。
作成するファイルは src/main/resources/archetype-resources/pom.xml と src/main/resources/archetype-resources/src/main/java/Sample.java の 2 つです。
src/main/resources/archetype-resources/pom.xml の内容は次のように作成します:
<project> <modelVersion>4.0.0</modelVersion> <groupId>${groupId}</groupId> <artifactId>${artifactId}</artifactId> <packaging>jar</packaging> <version>${version}</version> </project>
ここでのポイントは、「mvn archetype:create -DgroupId=...」コマンドを実行するときのパラメータを ${groupId} のように参照することができる点です。
次に作成されるプロジェクトの中身が空だと寂しいので、Java のソースコードを作成します。作成するのは src/main/resources/archetype-resources/src/main/java/Sample.java とし、以下の内容で作成します:
package ${groupId}; public class Sample { public static void main(String[] arguments) { System.out.println("Hello World"); } }
ここでも ${groupId} のようにパラメータを参照していることに注目してください。
7.16.4. archetype.xml の作成
次に src/main/resources/META-INF/archetype.xml を作成します。archetype.xml は Archetype に関する情報を記述するファイルです。今回は以下の内容で作成します:
<archetype> <id>maven-archetype-sample</id> <sources> <source>src/main/java/Sample.java</source> </sources> </archetype>
archetype.xml の書式は、全体を archetype 要素で囲みます。archetype 要素の中には、id (適当な識別子) と sources (スケルトンに含めるソースファイルの指定) を記述していますが、ほかにも resources 要素、testSources 要素、testResources 要素、siteResources 要素を含めることができます。
sources および testSources 要素には、複数の source 要素を含めることができます。source 要素では、ソース (またはテストソース) のファイルを指定します。
resources, testResources, siteResources 要素には、複数の resource 要素を含めることができます。resource 要素には、リソースとして含めたいファイルを指定します。
7.16.5. 作成した Archetype プロジェクトのインストール
これで maven-archetype-sample の作成は終了です。「mvn install」コマンドでプロジェクトをインストールして、maven-archetype-sample を使用可能な状態にしましょう。
7.16.6. maven-archetype-sample を使用する
それでは maven-archetype-sample を使用してプロジェクトを作成してみましょう。「mvn archetype:create」に渡すパラメータは、通常の groupId と artifactId のほかに、archetypeGroupId、archetypeArtifactId、archetypeVersion を指定する必要があります。
例えば groupId=hoge、artifactId=hoge というプロジェクトを maven-archetype-sample を用いて作成する場合は、次のコマンドを (改行をいれずに一行で) 実行します:
mvn archetype:create -DgroupId=hoge -DartifactId=hoge -DarchetypeGroupId=com.example.maven.archetype.sample -DarchetypeArtifactId=maven-archetype-sample -DarchetypeVersion=1.0
なお、今回作成した maven-archetype-sample のプロジェクトは、以下のリンクから入手することができます:
resource/maven-archetype-sample.lzh
7.17. native2ascii を実行する
現状の Maven で native2ascii を実行するには、maven-antrun-plugin を使用して、native2ascii を行う Ant タスクを実行するという方法をとります。
まず、pom.xml において maven-antrun-plugin の設定を行います:
<project ...> ... <build> ... <plugins> ... <plugin> <artifactId>maven-antrun-plugin</artifactId> <dependencies> <dependency> <groupId>sun.jdk</groupId> <artifactId>tools</artifactId> <version>1.5.0</version> <scope>system</scope> <systemPath>${env.JAVA_HOME}/lib/tools.jar</systemPath> </dependency> <dependency> <groupId>ant</groupId> <artifactId>ant-nodeps</artifactId> <version>1.7.5</version> </dependency> </dependencies> <executions> <execution> <!-- id タグは executions 内に複数の execution タグを含める場合に必要. --> <id>native2ascii</id> <phase>process-resources</phase> <configuration> <tasks> <!-- ここに Ant のタスクを記述する. ここでは別ファイルとして用意した build.xml の native2ascii を実行する. --> <ant antfile="build.xml" target="native2ascii" inheritRefs="true" /> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> ... </plugins> ... </build> ... </project>
要点をまとめると:
- プラグインが依存しているライブラリを plugin の入れ子の dependencies 要素で指定します。
- process-resources フェイズが実行されるときにプラグインが実行されるように、execution の入れ子の phase 要素で「process-resources」を指定します。
- configuration の入れ子の tasks 要素の中に実行したいタスクを記述します。
この例では、実行するタスクとして、別ファイルとして用意した build.xml に含まれる native2ascii ターゲットを実行するようにしています。
build.xml の内容は以下のようになります:
<project> <!-- リソース・ファイル ( .properties ファイルなど) の置かれるディレクトリ. --> <property name="resource.dir" value="src/main/resources" /> <!-- コンパイル済みクラスファイルの出力先ディレクトリ. このディレクトリに変換後の .properties ファイルも出力します. --> <property name="classes.dir" value="target/classes" /> <!-- リソース・ファイル (.properties ファイルなど) のエンコーディング. --> <property name="resource.encoding" value="Windows-31J" /> <!-- native2ascii により .properties ファイルを変換します. --> <target name="native2ascii"> <mkdir dir="${classes.dir}" /> <delete dir="${classes.dir}" includes="**/*.properties" /> <native2ascii src="${resource.dir}" includes="**/*.properties" dest="${classes.dir}" encoding="${resource.encoding}" /> </target> </project>
maven-antrun-plugin のさらに詳しい情報は maven-antrun-plugin のサイトを、また Ant タスクの実行方法については「7.8. Ant タスクの実行方法」を参照してください。
7.18. Ant タスクの実行方法
Maven から Ant タスクを呼び出すには、maven-antrun-plugin を使用します。
以下に例として compile フェイズに Ant の echo タスクで "Hello Ant from Maven" という文字列を表示する場合の設定例を示します:
<project ...> ... <build> ... <plugins> ... <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <!-- id タグは executions 内に複数の execution タグを含める場合に必要. --> <id>echo</id> <phase>compile</phase> <configuration> <tasks> <!-- ここに Ant のタスクを記述する. --> <echo message="Hello Ant from Maven" /> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> ... </plugins> ... </build> ... </project>
実行する Ant タスクによっては、他のライブラリを必要とする場合があります。その場合は、plugin/dependencies 要素以下に必要な情報を記述します。(それについては「7.9. プラグインを特定のフェイズで実行する」や「7.17. native2ascii を実行する」を参考にしてください。
maven-antrun-plugin のさらに詳しい情報は、maven-antrun-plugin のサイト を参照してください。
7.19. プラグインを特定のフェイズで実行する
プラグインの基本的な設定方法は「3.2.1. プラグインの設定方法」において説明しましたが、ここでは特定のフェイズにプラグインを実行する方法について説明します。
pom.xml での設定の基本的な形は、次のようになります:
<project ...> ... <build> ... <plugins> ... <plugin> ... <dependencies> <!-- プラグインの依存するライブラリの設定. --> </dependencies> <executions> <execution> <id>適当な識別子. executions 内に複数の execution タグを含める場合に必要</id> <phase>プラグインを実行するフェイズ</phase> <configuration> <!-- プラグインの設定 (プラグインに依存する) --> </configuration> <goals> <goal>実行するプラグインのゴール</goal> </goals> </execution> </executions> </plugin> ... </plugins> ... </build> ... </project>
プラグインの実行をどのフェイズとも関連付けない場合は、plugin/configuration 要素に設定内容を記述しますが、特定のフェイズで実行する場合は、plugin/executions/execution 要素にプラグインの実行に関する情報を記述します。
execution 要素の中には、id (その execution の識別する値) や phase (プラグインを実行するフェイズ)、configuration (プラグインの設定)、goals/goal (実行するプラグインのゴール) を指定します。
id に関しては、executions に 1 つしか execution 要素を含まない場合は省略することができます。また、configuration で行うプラグインの設定に関しては、設定するプラグインのドキュメントを参照してください。