1.7. 比较Maven和Ant -maven权威指南
1.7. 比较Maven和Ant -maven权威指南
虽然上一节应该已经让你确信本书的作者没有兴趣挑起 Apache Ant 和 Apache Maven 之间的争执,但是我们认识到许多组织必须在 Apache Ant 和 Apache Maven 之间做一个选择。本节我们对比一下这两个工具。
Ant 在构建过程方面十分优秀,它是一个基于任务和依赖的构建系统。每个任务包含一组由 XML 编码的指令。有 copy
任务和 javac
任务,以及 jar
任务。在你使用 Ant 的时候,你为 Ant 提供特定的指令以编译和打包你的输出。看下面的例子,一个简单的 build.xml
文件:
Example 1.1. 一个简单的 Ant build.xml 文件
<project name="my-project" default="dist" basedir=".">
<description>
simple example build file
</description>
<>
<property name="src" location="src/main/java"/>
<property name="build" location="target/classes"/>
<property name="dist" location="target"/>
<target name="init">
<>
<tstamp/>
<>
<mkdir dir="org.apache.maven.model.Build@6130fa43"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<>
<javac srcdir="${src}" destdir="org.apache.maven.model.Build@6130fa43"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<>
<mkdir dir="${dist}/lib"/>
<>
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="org.apache.maven.model.Build@6130fa43"/>
</target>
<target name="clean"
description="clean up" >
<>
<delete dir="org.apache.maven.model.Build@6130fa43"/>
<delete dir="${dist}"/>
</target>
</project>
在这个简单的 Ant 例子中,你能看到,你需要明确的告诉 Ant 你想让它做什么。有一个包含 javac
任务的编译目标用来将 src/main/java
的源码编译至 target/classes
目录。你必须明确告诉 Ant 你的源码在哪里,结果字节码你想存储在哪里,如何将这些字节码打包成 JAR 文件。虽然最近有些进展以帮助 Ant 减少程序,但一个开发者对 Ant 的感受是用 XML 编写程序语言。
用 Maven 样例与之前的 Ant 样例做个比较。在 Maven 中,要从 Java 源码创建一个 JAR 文件,你只需要创建一个简单的 pom.xml
,将你的源码放在 /data/hudson-temporal-data/hudson-orchestrator-home/workspace/Book-To-Production/book/content-zh/src/main/java
,然后从命令行运行 mvn install。下面的样例 Maven pom.xml
文件能完成和之前 Ant 样例所做的同样的事情。
Example 1.2. 一个简单的 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 site ,然后在 target/site
目录找到一个 index.html
文件,这个文件链接了 JavaDoc 和一些关于源代码的报告。
诚然,这是一个最简单的样例项目。一个只包含源代码并且生成一个 JAR 的项目。一个遵循 Maven 的约定,不需要任何依赖和定制的项目。如果我们想要定制行为,我们的 pom.xml
的大小将会增加,在最大的项目中,你能看到一个非常复杂的 Maven POM 的集合,它们包含了大量的插件定制和依赖声明。但是,虽然你项目的 POM 文件变得增大,它们包含的信息与一个差不多大小的基于 Ant 项目的构建文件的信息是完全不同的。Maven POM 包含声明:“这是一个 JAR 项目”,“源代码在 src/main/java
目录”。Ant 构建文件包含显式的指令:“这是一个项目”,“源代码在 src/main/java
”,“针对这个目录运行 javac ”,“把结果放到 target/classes
”,“从……创建一个 JAR ”,等等。Ant 必须的过程必须是显式的,而 Maven 有一些“内置”的东西使它知道源代码在哪里,如何处理它们。
该例中 Ant 和 Maven 的区别是:
Apache Ant
-
-
Ant 没有正式的约定如一个一般项目的目录结构,你必须明确的告诉 Ant 哪里去找源代码,哪里放置输出。随着时间的推移,非正式的约定出现了,但是它们还没有在产品中模式化。
-
Ant 是程序化的,你必须明确的告诉 Ant 做什么,什么时候做。你必须告诉它去编译,然后复制,然后压缩。
-
Ant 没有生命周期,你必须定义目标和目标之间的依赖。你必须手工为每个目标附上一个任务序列。
Apache Maven
-
-
Maven 拥有约定,因为你遵循了约定,它已经知道你的源代码在哪里。它把字节码放到 target/classes
,然后在 target
生成一个 JAR 文件。
-
Maven 是声明式的。你需要做的只是创建一个 pom.xml 文件然后将源代码放到默认的目录。Maven 会帮你处理其它的事情。
-
Maven 有一个生命周期,当你运行 mvn install 的时候被调用。这条命令告诉 Maven 执行一系列的有序的步骤,直到到达你指定的生命周期。遍历生命周期旅途中的一个影响就是,Maven 运行了许多默认的插件目标,这些目标完成了像编译和创建一个 JAR 文件这样的工作。
Maven 以插件的形式为一些一般的项目任务提供了内置的智能。如果你想要编写运行单元测试,你需要做的只是编写测试然后放到 /data/hudson-temporal-data/hudson-orchestrator-home/workspace/Book-To-Production/book/content-zh/src/test/java
,添加一个对于 TestNG 或者 JUnit 的测试范围依赖,然后运行 mvn test 。如果你想要部署一个 web 应用而非 JAR ,你需要做的是改变你的项目类型为 war ,然后把你文档根目录置为 /data/hudson-temporal-data/hudson-orchestrator-home/workspace/Book-To-Production/book/content-zh/src/main/webapp
。当然,你可以用 Ant 做这些事情,但是你将需要从零开始写这些指令。使用 Ant ,你首先需要确定 JUnit JAR 文件应该放在哪里,然后你需要创建一个包含这个 JUnit JAR 文件的 classpath ,然后告诉 Ant 它应该从哪里去找测试源代码,编写一个目标来编译测试源代码为字节码,使用 JUnit 来执行单元测试。
没有诸如 antlibs 和 lvy 等技术的支持(即使有了这些支持技术),Ant 给人感觉是自定义的程序化构建。项目中一组高效的坚持约定的 Maven POM ,相对于 Ant 的配置文件,只有很少的 XML 。Maven 的另一个优点是它依靠广泛公用的 Maven 插件。所有人使用 Maven Surefire 插件来运行单元测试,如果有人添加了一些针对新的测试框架的支持,你可以仅仅通过在你项目的 POM 中升级某个特定插件的版本来获得新的功能。
使用 Maven 还是 Ant 的决定不是非此即彼的,Ant 在复杂的构建中还有它的位置。如果你目前的构建包含一些高度自定义的过程,或者你已经写了一些 Ant 脚本通过一种明确的方法完成一个明确的过程,而这种过程不适合 Maven 标准,你仍然可以在 Maven 中用这些脚本。作为一个 Maven 的核心插件, Ant 还是可用的。自定义的插件可以用 Ant 来实现,Maven 项目可以配置成在生命周期中运行 Ant 的脚本。
当然,Maven 是 Ant 的另一种选择,但是 Apache Ant 继续是一个伟大的,被广泛使用的工具。它已经是多年以来 Java 构建的统治者,而你很容易的在你项目的 Maven 构建中集成 Ant 构建脚本。这是 Maven 项目一种很常见的使用模式。而另一方面,随着越来越多的开源项目转移到 Maven 用它作为项目管理平台,开发人员开始意识到 Maven 不仅仅简化了构建管理任务,它也帮助鼓励开发人员的软件项目使用通用的接口。Maven 不仅仅是一个工具,它更是一个平台,当你只是将 Maven 考虑成 Ant 的另一种选择的时候,你是在比较苹果和橘子。“Maven”包含了很多构建工具以外的东西。
有一个核心观点使得所有的关于 Maven 和. Ant, Maven 和 Buildr, Maven 和 Grandle 的争论变得无关紧要。Maven并不是完全根据你构建系统的机制来定义的,它不是为你构建的不同任务编写脚本,它提倡一组标注,一个一般的接口,一个生命周期,一个标准的仓库格式,一个标准的目录布局,等等。它当然也不太在意 POM 的格式正好是 XML 还是 YAML 还是 Ruby。它比这些大得多,Maven 涉及的比构建工具本身多得多。当本书讨论 Maven 的时候,它也设计到支持 Maven 的软件,系统和标准。Buildr,Ivy,Gradle,所有这些工具都和 Maven 帮助创建的仓库格式交互,而你可以很容易的使用如 Nexus 这样的工具来支持一个完全由 Buildr 编写的构建。Nexus 将在本书后面介绍。
虽然 Maven 是很多类似工具的另一个选择?但社区需要向前发展,就要看清楚技术是资本经济中不友好的竞争者之间持续的、零和的游戏。这可能是大企业之前相互关联的方式,但是和开源社区的工作方式没太大关系。“谁是胜利者?Ant 还是 Maven”这个大标题没什么建设性意义。如果你非要我们来回答这个问题,我们会很明确的说作为构建的基本技术,Maven 是 Ant 的更好选择;同时,Maven 的边界在持续的移动,Maven 的社区也在持续的是试图找到新的方法,使其更通用,互操作性更好,更易协同工作。Maven 的核心财产是声明性构建,依赖管理,仓库管理,基于插件的高度和重用,但是当前,和开源社区相互协作以降低”企业级构建“的低效率这个目标来比,这些想法的特定实现没那么重要。
Maven权威指南 http://www.sonatype.com/books/maven-book/reference_zh/public-book.html
Maven中文 http://juvenshun.javaeye.com/
如何回答这个问题要看你怎么看这个问题。 绝大部分Maven用户都称Maven是一个"构建工具":一个用来把源代码构建成可发布的构件的工具。 构建工程师和项目经理会说Maven是一个更复杂的东西:一个项目管理工具。那么区别是什么? 像Ant这样的构建工具仅仅是关注预处理,编译,打包,测试和分发。像 Maven 这样的一个项目管理工具提供了构建工具所提供功能的超集。 除了提供构建的功能,Maven还可以生成报告,生成Web站点,并且帮助推动工作团 队成员间的交流。
一个更正式的 Apache Maven 的定义: Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。 当你使用Maven的时候,你用一个明确定义的项目对象模型来描述你的项目,然后 Maven 可以应用横切的逻辑,这些逻辑来自一组共享的(或者自定义的)插件。
别让Maven是一个"项目管理"工具的事实吓跑你。如果你只是在找一个构建工具,Maven能做这个工作。 事实上,本书的一些章节将会涉及使用Maven来构建和分发你的项目。