Ant と Maven の違いを教えてもらえますか? 私も使ったことはありません。Java プロジェクトのビルドを自動化するために使用されることは理解していますが、どこから始めればよいかわかりません。
9 に答える
Maven: The Definitive Guideでは、 「Ant と Maven の違い」というセクション タイトルの紹介で、Maven と Ant の違いについて書きました。その紹介の情報といくつかの追加のメモを組み合わせた回答を次に示します。
簡単な比較
これは、最も基本的なレベルで、Maven には組み込みの規則があるという考えを説明するためだけに示しています。簡単な Ant ビルド ファイルを次に示します。
<project name="my-project" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src/main/java"/>
<property name="build" location="target/classes"/>
<property name="dist" location="target"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file
-->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>
この単純な Ant の例では、Ant に何をすべきかを正確に伝える方法を確認できます。src/main/java ディレクトリのソースを target/classes ディレクトリにコンパイルする javac タスクを含むコンパイルの目標があります。ソースの場所、結果のバイトコードを格納する場所、およびこれらすべてを JAR ファイルにパッケージ化する方法を Ant に正確に伝える必要があります。Ant の手続き型を減らすのに役立つ最近の開発がいくつかありますが、Ant に関する開発者の経験は、XML で記述された手続き型言語のコーディングです。
前の Ant の例と Maven の例を比較してください。Maven で Java ソースから JAR ファイルを作成するには、単純な pom.xml を作成し、ソース コードを ${basedir}/src/main/java に配置して、コマンド ラインから mvn install を実行するだけです。 . 同じ結果が得られる Maven pom.xml の例。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>
pom.xml で必要なのはこれだけです。コマンド ラインから mvn install を実行すると、リソースが処理され、ソースがコンパイルされ、単体テストが実行され、JAR が作成され、他のプロジェクトで再利用できるように JAR がローカル リポジトリにインストールされます。変更しなくても、mvn サイトを実行すると、JavaDoc へのリンクとソース コードに関するいくつかのレポートを含む target/site 内の index.html ファイルを見つけることができます。
確かに、これは可能な限り単純なサンプル プロジェクトです。ソース コードのみを含み、JAR を生成するプロジェクト。Maven の規則に従い、依存関係やカスタマイズを必要としないプロジェクト。動作のカスタマイズを開始したい場合は、pom.xml のサイズが大きくなり、最大のプロジェクトでは、大量のプラグインのカスタマイズと依存関係の宣言を含む非常に複雑な Maven POM のコレクションを見ることができます。ただし、プロジェクトの POM ファイルがより充実したものになっても、Ant を使用した同様のサイズのプロジェクトのビルド ファイルとはまったく異なる種類の情報が保持されます。Maven POM には、「これは JAR プロジェクトです」および「ソース コードは src/main/java にあります」という宣言が含まれています。Ant ビルド ファイルには、「これはプロジェクトです」、「src/main/java
javac
"、"このディレクトリに対して実行" 、"結果をtarget/classses
"、"....から JAR を作成" など。ソースコードがどこにあり、どのように処理する必要があるかを知っているだけです。
高レベルの比較
この例での Ant と Maven の違いは? 蟻...
- には、一般的なプロジェクト ディレクトリ構造のような正式な規則はありません。ソースを見つける場所と出力を配置する場所を Ant に正確に伝える必要があります。時間の経過とともに非公式の慣習が生まれましたが、製品には体系化されていません。
- は手続き型なので、何をいつ行うかを Ant に正確に伝える必要があります。コンパイルしてからコピーしてから圧縮するように指示する必要がありました。
- にはライフサイクルがないため、目標と目標の依存関係を定義する必要がありました。一連のタスクを各目標に手動で添付する必要がありました。
メイヴンはどこ...
- には規則があります。規則に従っているため、ソース コードがどこにあるかは既にわかっています。バイトコードを target/classes に配置し、JAR ファイルを target に生成しました。
- 宣言的です。pom.xml ファイルを作成し、ソースをデフォルト ディレクトリに配置するだけで済みました。Mavenが残りの面倒を見てくれました。
- には、実行時に呼び出したライフサイクルがあります
mvn install
。このコマンドは、ライフサイクルに達するまで一連のシーケンス ステップを実行するように Maven に指示します。このライフサイクルの旅の副作用として、Maven は、コンパイルや JAR の作成などを行う多くのデフォルトのプラグイン ゴールを実行しました。
アイビーは?
そうです、スティーブ・ローランのような誰かがその比較を読んでファウルを呼ぶでしょう。彼は、回答が Ivy と呼ばれるものを完全に無視していることと、Ant の最近のリリースで Ant がビルド ロジックを再利用できるという事実について話します。これは本当です。Ant + antlibs + Ivy を使用している賢い人がたくさんいる場合は、適切に設計されたビルドが機能することになります。とはいえ、Maven が理にかなっているという確信はありますが、非常に鋭いビルド エンジニアを擁するプロジェクト チームで Ant + Ivy を喜んで使用したいと思います。そうは言っても、Jetty プラグインなどの多くの貴重なプラグインを見逃してしまい、時間の経過とともに必要のない多くの作業を行うことになると思います.
Maven 対 Ant よりも重要
- リポジトリ マネージャーを使用してソフトウェア アーティファクトを追跡するということですか。Nexus をダウンロードすることをお勧めします。Nexus を使用して、リモート リポジトリをプロキシし、チームが内部アーティファクトを展開する場所を提供できます。
- ソフトウェア コンポーネントの適切なモジュール化があります。1 つの大きなモノリシック コンポーネントが時間の経過とともにスケーリングされることはめったにありません。プロジェクトが発展するにつれて、モジュールとサブモジュールの概念が必要になります。Maven は、このアプローチに非常に適しています。
- ビルドにいくつかの規則を採用します。Ant を使用する場合でも、他のプロジェクトと一貫性のある形式の規則を採用するよう努めるべきです。プロジェクトが Maven を使用する場合、Maven に精通している人なら誰でもビルドを取得して実行を開始できることを意味します。コンパイルする方法を理解するためだけに構成をいじる必要はありません。
Maven はフレームワーク、Ant はツールボックス
Maven は組み立て済みのロードカーですが、Ant は自動車部品のセットです。Ant では自分の車を作る必要がありますが、少なくともオフロードでの運転が必要な場合は、適切なタイプの車を作ることができます。
別の言い方をすれば、Maven はフレームワークであり、Ant はツールボックスです。フレームワークの範囲内で作業することに満足している場合は、Maven で十分です。私にとっての問題は、フレームワークの境界にぶつかり続け、それが私を解放しないことでした。
XML の冗長性
tobrien は Maven についてよく知っている人物であり、2 つの製品の非常に優れた率直な比較を提供してくれたと思います。彼は単純な Maven pom.xml を単純な Ant ビルド ファイルと比較し、Maven プロジェクトがどのように複雑になるかについて言及しました。単純な実際のプロジェクトで目にする可能性が高いいくつかのファイルを比較してみる価値があると思います。以下のファイルは、マルチモジュール ビルドの単一モジュールを表しています。
まず、Maven ファイル:
<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-4_0_0.xsd">
<parent>
<groupId>com.mycompany</groupId>
<artifactId>app-parent</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>persist</artifactId>
<name>Persistence Layer</name>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>common</artifactId>
<scope>compile</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>domain</artifactId>
<scope>provided</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernate.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>${spring.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${commons-dbcp.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>${oracle-jdbc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>${easymock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
同等の Ant ファイル:
<project name="persist" >
<import file="../build/common-build.xml" />
<path id="compile.classpath.main">
<pathelement location="${common.jar}" />
<pathelement location="${domain.jar}" />
<pathelement location="${hibernate.jar}" />
<pathelement location="${commons-lang.jar}" />
<pathelement location="${spring.jar}" />
</path>
<path id="compile.classpath.test">
<pathelement location="${classes.dir.main}" />
<pathelement location="${testng.jar}" />
<pathelement location="${dbunit.jar}" />
<pathelement location="${easymock.jar}" />
<pathelement location="${commons-dbcp.jar}" />
<pathelement location="${oracle-jdbc.jar}" />
<path refid="compile.classpath.main" />
</path>
<path id="runtime.classpath.test">
<pathelement location="${classes.dir.test}" />
<path refid="compile.classpath.test" />
</path>
</project>
tobrien は彼の例を使用して、Maven には組み込みの規則があることを示しましたが、それは必ずしも XML の記述が少なくなることを意味するわけではありません。私はその反対が真実であることを発見しました。pom.xml は build.xml の 3 倍の長さであり、規則から逸脱することはありません。実際、私の Maven の例では、プラグインの構成に必要な余分な 54 行が省略されています。その pom.xml は単純なプロジェクト用です。追加の要件を追加し始めると、XML は実際に大幅に成長し始めますが、これは多くのプロジェクトでは普通のことです。
ただし、Ant に何をすべきかを伝える必要があります。
もちろん、上記の Ant の例は完全ではありません。クリーン、コンパイル、テストなどに使用するターゲットを定義する必要があります。これらは、マルチモジュール プロジェクトのすべてのモジュールによってインポートされる共通のビルド ファイルで定義されます。これは、Mavenでは宣言的であるのに対し、Antではこれらすべてを明示的に記述する必要があるという点に私を導きます。
確かに、これらの Ant ターゲットを明示的に記述する必要がなければ、時間を節約できます。しかし、どのくらいの時間ですか?私が現在使用している一般的なビルド ファイルは、5 年前に作成したもので、それ以降はわずかに改良されています。Maven を 2 年間試した後、クローゼットから古い Ant ビルド ファイルを取り出し、ほこりを払い、元に戻しました。私にとって、Ant に何をすべきかを明示的に伝えなければならないコストは、5 年間で 1 週間もかからなかった。
複雑
次に言及したい大きな違いは、複雑さとそれが持つ現実世界への影響です。Maven は、ビルド プロセスの作成と管理を担当する開発者の作業負荷を軽減することを目的として構築されました。これを行うには、複雑にする必要があります。残念ながら、その複雑さは意図した目標を無効にする傾向があります。
Ant と比較すると、Maven プロジェクトのビルド担当者はより多くの時間を費やします。
- ドキュメントを読む: Maven に関するドキュメントは他にもたくさんあります。
- チーム メンバーの教育: 自分で答えを見つけようとするよりも、知っている人に尋ねる方が簡単です。
- ビルドのトラブルシューティング: Maven は Ant よりも信頼性が低く、特にコア以外のプラグインは信頼性が低くなります。また、Maven ビルドは反復できません。プラグインの SNAPSHOT バージョンに依存している場合 (ほとんどの場合)、何も変更していなくてもビルドが壊れる可能性があります。
- Maven プラグインの作成: プラグインは通常、特定のタスクを念頭に置いて作成されます。たとえば、Webstart バンドルを作成すると、他のタスクでプラグインを再利用したり、目的を達成するためにそれらを組み合わせたりすることが難しくなります。そのため、既存のプラグイン セットのギャップを回避するために、独自のものを作成する必要がある場合があります。
対照的に:
- Ant のドキュメントは簡潔で包括的で、すべてが 1 か所にまとめられています。
- アリは単純です。Ant を学ぼうとしている新しい開発者は、いくつかの簡単な概念 (ターゲット、タスク、依存関係、プロパティ) を理解するだけで、残りの知識を理解することができます。
- アリは信頼できる。Ant は既に動作しているため、過去数年間、Ant のリリースはあまり多くありません。
- Ant ビルドは通常、オンライン リポジトリや実験的なサードパーティ プラグインなどの外部依存関係なしで作成されるため、反復可能です。
- Ant は包括的です。ツールボックスであるため、ツールを組み合わせて、必要なほぼすべてのタスクを実行できます。独自のカスタム タスクを作成する必要がある場合は、非常に簡単に行うことができます。
親しみやすさ
もう1つの違いは、親しみやすさです。新しい開発者は常に、スピードに慣れるまでに時間がかかります。その点では、既存の製品に精通していると役立ちます。Maven の支持者は、これが Maven の利点であると主張しています。もちろん、Ant の柔軟性は、好きなように規則を作成できることを意味します。したがって、私が使用する規則は、ソース ファイルをディレクトリ名 src/main/java に置くことです。コンパイルしたクラスは、target/classes という名前のディレクトリに入ります。おなじみですね。
Maven が使用するディレクトリ構造が気に入っています。理にかなっていると思います。また、ビルドのライフサイクル。そのため、Ant ビルドでも同じ規則を使用しています。理にかなっているという理由だけでなく、以前に Maven を使用したことがある人にはなじみがあるからです。
Ant は主にビルド ツールです。
Maven は、プロジェクトと依存関係の管理ツールです (もちろん、プロジェクトもビルドされます)。
Ant+ Ivyは、Maven を避けたい場合に最適な組み合わせです。
いくつかの違いをリストするだけです:
- Ant には正式な規則はありません。ソースを見つける場所、出力を配置する場所などを Ant に正確に伝える必要があります。
- Ant は手続き型です。何をすべきかを Ant に正確に伝える必要があります。コンパイル、コピー、圧縮などを指示します。
- Ant にはライフサイクルがありません。
- Maven は規則を使用します。これらの規則に従っている限り、ソース コードがどこにあるかが自動的に認識されます。その場所を Maven に伝える必要はありません。
- Maven は宣言型です。pom.xml ファイルを作成し、ソースをデフォルト ディレクトリに配置するだけです。残りは Maven が処理します。
- Maven にはライフサイクルがあります。mvn installを呼び出すだけで、一連のシーケンス ステップが実行されます。
- Maven には、一般的なプロジェクト タスクに関するインテリジェンスがあります。テストを実行するには、ファイルがデフォルトの場所にある限り、単純にmvn testを実行します。Ant では、最初に JUnit JAR ファイルを作成し、JUnit JAR を含むクラスパスを作成し、テスト ソース コードを探す場所を Ant に指示し、テスト ソースをコンパイルするゴールを記述し、最後に単体テストを実行する必要があります。 JUnitで。
アップデート:
これはMaven: The Definitive Guideからのものです。すみません、引用するのをすっかり忘れていました。
MavenまたはAnt?これと非常によく似た質問です。質問に答えるのに役立ちます。
メイヴンとは?公式サイトで。
編集:新規/グリーンフィールド プロジェクトの場合、Maven を使用することをお勧めします。「構成よりも規約」を使用すると、ビルド スクリプトとデプロイ スクリプトの作成と設定にかなりの時間を節約できます。ant を使用する場合、ビルド スクリプトは時間の経過とともに長くなり、複雑になる傾向があります。既存のプロジェクトの場合、その構成/レイアウトを Maven システムに押し込むのは難しい場合があります。
Maven は、依存関係管理ツール (中央リポジトリまたは設定したリポジトリから jar を取得するために使用できます) と宣言型ビルド ツールの両方として機能します。「宣言型」のビルド ツールと、ant や make などのより伝統的なビルド ツールの違いは、実行方法ではなく、何を実行する必要があるかを構成することです。たとえば、maven スクリプトで、プロジェクトを WAR ファイルとしてパッケージ化する必要があると言うことができ、maven はそれを処理する方法を知っています。
Maven は、その「宣言性」を実現するために、プロジェクト ディレクトリがどのようにレイアウトされるかについての規則に依存しています。たとえば、メイン コードを配置する場所、web.xml や単体テストを配置する場所などの規則がありますが、必要に応じてそれらを変更することもできます。
Maven 内から ant コマンドを実行するためのプラグインがあることにも注意してください。
http://maven.apache.org/plugins/maven-ant-plugin/
また、maven のアーキタイプにより、プロジェクトを非常に迅速に開始できます。たとえば、Wicket アーキタイプがあります。これは、すぐに実行できる hello ワールド タイプのプロジェクト全体を取得するために実行する Maven コマンドを提供します。
私は Ant を見たことがない人を取り上げることができます - Antbuild.xml
はかなりよく書かれています - 彼らは何が起こっているのか理解できます。その同じ人に Maven POM を見せても、彼らは何が起こっているのかまったくわかりません。
巨大なエンジニアリング組織では、Ant ファイルが大きくなり、管理できなくなると書いています。私はそれらの型ときれいな Ant スクリプトを書きました。それは、今後何をする必要があるかを事前に理解し、3 年以上にわたる変化と拡張に対応できる一連のテンプレートを設計することです。
単純なプロジェクトでない限り、Maven の規則と Maven の方法を習得して作業を完了するのは、かなりの労力を要します。
結局のところ、Ant や Maven を使用したプロジェクトの開始を要因と見なすことはできません。それは実際には総所有コストです。組織が数年にわたってビルド システムを維持および拡張するために必要なことは、考慮しなければならない主な要因の 1 つです。
ビルド システムの最も重要な側面は、依存関係の管理と、ビルド レシピを表現する際の柔軟性です。うまくやれば、いくぶん直感的になるはずです。
プロジェクトのサイズにもよると思います...個人的には、簡単なコンパイル、パッケージ化、および展開が必要な単純なプロジェクトには Maven を使用します。より複雑なこと (多くの依存関係、マッピング ファイルの作成など) を行う必要があるとすぐに、私は Ant に切り替えます...
Maven には、一般的に使用されるオープン ソース プロジェクトの大規模なリポジトリも格納されています。ビルド中に、Maven はこれらの依存関係 (および依存関係の依存関係) をダウンロードして、プロジェクトのビルドのこの部分をもう少し管理しやすくすることができます。