誰かがAntとMavenの違いを教えてもらえますか?私も使用したことがありません。 Javaプロジェクトの構築を自動化するために使用されることは理解していますが、どこから始めればよいのかわかりません。
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タスクを含むコンパイルの目標があります。 Antにソースがどこにあるか、結果のバイトコードをどこに保存するか、これをすべてJARファイルにパッケージ化する方法を正確に伝える必要があります。 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へのリンクとソースコードに関するいくつかのレポートを含むindex.htmlファイルをtarget/siteで見つけることができます。
確かに、これは可能な限り単純なプロジェクト例です。ソースコードのみを含み、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とMavenの違いは?蟻...
どこMaven ...
mvn install
を実行したときに呼び出したライフサイクルがあります。このコマンドは、ライフサイクルに到達するまで一連のシーケンスステップを実行するようにMavenに指示しました。ライフサイクル全体のこの旅の副作用として、Mavenは、JARのコンパイルや作成などを行う多くのデフォルトのプラグイン目標を実行しました。アイビーはどうですか?
そうです、スティーブ・ラフランのような人がその比較を読んで、ファウルを呼ぶでしょう。彼は、答えがIvyと呼ばれるものを完全に無視する方法と、Antの最近のリリースでビルドロジックを再利用できるという事実について説明します。これは本当です。 Ant + antlibs + Ivyを使用している優秀な人々がいる場合、うまく機能する適切に設計されたビルドになります。 Mavenが理にかなっていると確信していますが、非常に鋭いビルドエンジニアがいるプロジェクトチームでAnt + Ivyを喜んで使用します。そうは言っても、Jettyプラグインなどの多くの貴重なプラグインを見逃してしまうことになると思います。
Maven対Antよりも重要
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プロジェクトのビルド担当者はより多くの時間を費やします。
対照的に:
親しみやすさ
もう1つの違いは、親しみやすさです。新しい開発者は、常に速度を上げるのに時間が必要です。既存の製品に精通していることがその点で役立ち、MavenサポーターはこれがMavenの利点であると正しく主張しています。もちろん、Antの柔軟性により、好みの規則を作成できます。したがって、私が使用する規則は、ソースファイルをディレクトリ名src/main/Javaに置くことです。コンパイルしたクラスは、target/classesという名前のディレクトリに配置されます。おなじみの音はしません。
Mavenで使用されるディレクトリ構造が好きです。理にかなっていると思います。また、ビルドのライフサイクル。したがって、Antビルドでも同じ規則を使用します。理にかなっているからというだけでなく、以前にMavenを使用したことがある人なら誰でも知っているからです。
Antは主にビルドツールです。
Mavenは、プロジェクトおよび依存関係管理ツールです(もちろん、プロジェクトもビルドします)。
Mavenを避けたい場合は、Ant + Ivy は非常に良い組み合わせです。
MavenまたはAnt? は、これと非常によく似た質問であり、質問に答えるのに役立ちます。
Mavenとは? 公式サイト.
edit:新規/グリーンフィールドプロジェクトの場合、Mavenを使用することをお勧めします。ビルドおよび展開スクリプトのセットアップ。 antを使用すると、ビルドスクリプトは時間の経過とともに複雑さを増していく傾向があります。既存のプロジェクトの場合、Mavenシステムに構成/レイアウトを簡単に追加することは困難です。
さらにいくつかの違いをリストするために:
更新:
これは、 Maven:The Definitive Guide に由来します。申し訳ありませんが、引用するのを完全に忘れていました。
Mavenは、依存関係管理ツール(中央リポジトリまたは設定したリポジトリからjarを取得するために使用できます)と宣言型ビルドツールの両方として機能します。 「宣言」ビルドツールとantやmakeなどの従来のツールとの違いは、実行方法ではなく、実行する必要があるものを設定することです。たとえば、mavenスクリプトで、プロジェクトをWARファイルとしてパッケージ化する必要があると言うことができ、mavenはそれを処理する方法を知っています。
Mavenは、その「宣言性」を実現するためにプロジェクトディレクトリをどのようにレイアウトするかについての規則に依存しています。たとえば、メインコードを配置する場所、web.xml、ユニットテストなどを配置する規則がありますが、必要に応じて変更することもできます。
また、Maven内からantコマンドを実行するためのプラグインがあることに留意する必要があります。
http://maven.Apache.org/plugins/maven-ant-plugin/
また、mavenのアーキタイプにより、プロジェクトをすぐに開始できます。たとえば、Wicketアーキタイプがあります。これは、実行可能なhello worldタイプのプロジェクト全体を取得するために実行するmavenコマンドを提供します。
Antを見たことのない人を連れて行くことができます-そのbuild.xml
sはかなりよく書かれています-そして彼らは何が起こっているのか理解できます。私はその同じ人を連れてMaven POMを見せることができます。
巨大なエンジニアリング組織では、Antファイルが大きくなり、管理不能になることについて人々が書きます。これらのタイプを記述しましたand Clean Antスクリプト。今後何をする必要があるかを事前に理解し、3年以上にわたって変化に対応し、拡張できるテンプレートのセットを設計しています。
単純なプロジェクトがない限り、物事を成し遂げるためのMavenの規則とMavenの方法を学ぶのはかなりの作業です。
結局のところ、AntまたはMavenを使用したプロジェクトの開始を要因と見なすことはできません。それは実際には総所有コストです。組織が数年にわたってビルドシステムを維持および拡張するために必要なことは、考慮しなければならない主な要因の1つです。
ビルドシステムの最も重要な側面は、依存関係の管理とビルドレシピの表現における柔軟性です。うまくやれば、やや直感的でなければなりません。
私はそれがあなたのプロジェクトのサイズに依存すると言うだろう...個人的に、私は簡単なコンパイル、パッケージング、展開を必要とする単純なプロジェクトにMavenを使用します。もっと複雑なこと(多くの依存関係、マッピングファイルの作成など)を行う必要があるとすぐに、Antに切り替えます...
Mavenには、一般的に使用されるオープンソースプロジェクトの大規模なリポジトリもあります。ビルド中に、Mavenはこれらの依存関係(および依存関係の依存関係)をダウンロードして、プロジェクトのビルドのこの部分をもう少し管理しやすくします。