有人可以告诉我Ant和Maven之间的区别吗?我也从未用过。我知道它们是用来自动构建Java项目的,但是我不知道从哪里开始。
有人可以告诉我Ant和Maven之间的区别吗?我也从未用过。我知道它们是用来自动构建Java项目的,但是我不知道从哪里开始。
Answers:
在“ Maven:权威指南”中,我在引言中写了有关Maven和Ant之间的区别的部分,标题为“ Ant和Maven之间的区别”。这是一个答案,该答案是该简介中的信息与一些其他说明的结合。
简单比较
我仅向您显示这是为了说明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该做什么。有一个编译目标,其中包括javac任务,该任务将src / main / java目录中的源编译为target / classes目录。您必须准确告诉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 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/classses
”,“从...创建一个JAR”等。在必须明确说明该过程的地方,Maven有一些“内置”功能只是知道源代码在哪里以及应该如何处理。
高层比较
在这个例子中,Ant和Maven之间的区别?蚂蚁...
Maven ...
mvn install
。该命令告诉Maven执行一系列序列步骤,直到到达生命周期。作为整个生命周期过程的副作用,Maven执行了许多默认插件目标,这些目标做了诸如编译和创建JAR之类的事情。那常春藤呢?
是的,所以像史蒂夫·拉夫兰(Steve Loughran)这样的人将阅读该比较报告并称犯规。他将谈论答案如何完全忽略Ivy,以及Ant可以在最新版的Ant中重用构建逻辑这一事实。这是真的。如果您有一群聪明的人使用Ant + antlibs + Ivy,那么您将得到一个设计良好且有效的构建。即使我非常相信Maven很有道理,但我很乐意将Ant + Ivy与一个拥有非常精明的构建工程师的项目团队一起使用。话虽这么说,但我确实认为您最终会错过许多有价值的插件,例如Jetty插件,并且最终将完成大量不必要的工作。
比Maven vs.Ant更重要
Maven是框架,Ant是工具箱
Maven是预制的公路车,而Ant是一组汽车零件。使用蚂蚁,您必须制造自己的汽车,但是至少如果您需要进行越野驾驶,则可以制造正确类型的汽车。
换句话说,Maven是一个框架,而Ant是一个工具箱。如果您对在框架范围内工作感到满意,那么Maven会做的很好。对我来说,问题在于我不断碰到框架的界限,而且不会让我失望。
XML详尽度
tobrien是一个非常了解Maven的人,我认为他对这两种产品进行了很好的诚实比较。他将简单的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目标,它将为我节省时间。但是多少时间?我现在使用的通用构建文件是我5年前编写的文件,此后仅作了一些细化。在对Maven进行2年的实验后,我将旧的Ant构建文件从壁橱中取出,除掉了灰尘,然后重新使用。对我来说,在5年的时间里,必须明确告诉Ant要做的事情加起来不到一周。
复杂
我要提及的下一个主要区别是复杂性及其所产生的现实效果。Maven的构建旨在减少负责创建和管理构建过程的开发人员的工作量。为此,它必须很复杂。不幸的是,这种复杂性往往会否定其预期目标。
与Ant相比,Maven项目的构建人员将花费更多时间:
相反:
熟识
另一个区别是熟悉度。新的开发人员总是需要时间来加快速度。熟悉现有产品在这方面有帮助,Maven支持者正确地声称这是Maven的好处。当然,Ant的灵活性意味着您可以创建自己喜欢的约定。因此,我使用的约定是将源文件放在目录名称src / main / java中。我编译的类进入名为target / classes的目录。听起来很熟悉,不是吗。
我喜欢Maven使用的目录结构。我认为这是有道理的。也是他们的构建生命周期。因此,我在Ant构建中使用了相同的约定。不仅因为它有意义,而且因为以前使用过Maven的任何人都会熟悉它。
pom.xml
s出现膨胀,我通过XSLT生成了其中的大多数。
仅列出更多差异:
更新:
这来自《Maven:权威指南》。抱歉,我完全忘了引用它。
Maven还是Ant?与这个问题非常相似,应该可以帮助您回答问题。
什么是Maven?在官方网站上。
编辑:对于一个新的/未开发的项目,我建议使用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原型,它提供了您运行的maven命令来获取一个完整的,随时可运行的hello世界类型的项目。
我可以带一个从未见过蚂蚁的人- build.xml
的语言写得不错-并且他们可以了解发生了什么。我可以带那个人给他们看一个Maven POM,他们不会知道发生了什么。
在庞大的工程组织中,人们会写关于Ant文件变得庞大且难以管理的文章。我已经写了那些类型,清理了Ant脚本。真正了解您需要做什么,并设计一套可以在3年以上的时间内响应变化和扩展的模板。
除非您有一个简单的项目,否则要学习Maven约定和Maven完成工作的方式,需要做很多工作。
归根结底,您不能将使用Ant或Maven启动项目视为一个因素:这实际上是总拥有成本。组织在几年内维护和扩展其构建系统所需要的是必须考虑的主要因素之一。
构建系统最重要的方面是依赖性管理和表达构建配方的灵活性。如果做得好,它必须有点直观。
我会说这取决于您项目的大小...就个人而言,我会将Maven用于需要直接编译,打包和部署的简单项目。一旦您需要做一些更复杂的事情(许多依赖项,创建映射文件...),我将切换到Ant ...
Maven还包含一个大型的常用开源项目存储库。在构建期间,Maven可以为您下载这些依赖项(以及您的依赖项依赖项:)),以使构建项目的这一部分更易于管理。