有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Ant和Maven之间的java差异

有人能告诉我Ant和Maven的区别吗?我也没用过。我知道它们用于自动化Java项目的构建,但我不知道从哪里开始


共 (6) 个答案

  1. # 1 楼答案

    Maven or Ant?是一个非常类似于这个问题的问题,它应该可以帮助你回答你的问题

    在官方网站上

    编辑:对于一个新的/greenfield项目,我建议使用Maven:“约定优先于配置”将为您节省大量编写、设置构建和部署脚本的时间。使用ant时,构建脚本的长度和复杂性会随着时间的推移而增加。对于现有项目,很难将它们的配置/布局硬塞进Maven系统

  2. # 2 楼答案

    我只想列出更多的区别:

    • 蚂蚁没有正式的约定。你必须准确地告诉Ant在哪里找到源,把输出放在哪里,等等
    • 蚂蚁是程序性的。你必须准确地告诉蚂蚁该做什么;告诉它编译、复制、然后压缩等等
    • 蚂蚁没有生命周期
    • Maven使用约定。只要遵循这些约定,它就会自动知道源代码在哪里。你不需要告诉Maven它在哪里
    • Maven是声明性的;你所要做的就是创建一个pom。xml文件,并将源代码放在默认目录中。马文会处理剩下的事
    • Maven有一个生命周期。只需调用mvn install即可执行一系列顺序步骤
    • Maven对常见的项目任务很有智慧。要运行测试,只需执行mvn test,只要文件位于默认位置。在Ant中,您首先需要知道JUnit JAR文件是什么,然后创建一个包含JUnit JAR的类路径,然后告诉Ant应该在哪里寻找测试源代码,编写一个编译测试源代码的目标,最后使用JUnit执行单元测试

    更新:

    这来自Maven: The Definitive Guide。对不起,我完全忘了引用它

  3. # 3 楼答案

    Ant主要是一个构建工具

    Maven是一个项目和依赖项管理工具(当然,它也会构建您的项目)

    如果你想避开Maven,Ant+Ivy是一个很好的组合

  4. # 4 楼答案

    Maven: The Definitive Guide中,我在导言中写到了Maven和Ant之间的差异,该部分的标题是"The Differences Between Ant and 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该做什么。有一个编译目标,包括将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站点,然后找到索引。目标/站点中的html文件,其中包含指向JavaDoc的链接和一些关于源代码的报告

    诚然,这是最简单的示例项目。只包含源代码并生成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之间的区别是什么?蚂蚁

    • 没有像公共项目目录结构这样的正式约定,您必须准确地告诉Ant在哪里找到源代码,在哪里放置输出。随着时间的推移,非正式的惯例已经出现,但它们还没有被编入产品中
    • 是程序性的,你必须准确地告诉Ant该做什么以及什么时候做。你必须让它编译,然后复制,然后压缩
    • 没有生命周期,你必须定义目标和目标依赖关系。您必须手动将一系列任务附加到每个目标

    在那里Maven

    • 有约定,它已经知道你的源代码在哪里,因为你遵循约定。它将字节码放入target/类中,并在target中生成一个JAR文件
    • 是声明性的。你所要做的就是创建一个pom。xml文件,并将源代码放在默认目录中。其余的由马文负责
    • 有一个生命周期,在执行^{时调用它。这个命令告诉Maven执行一系列序列直到达到生命周期。作为贯穿整个生命周期的一个副作用,Maven执行了许多默认插件目标,比如编译和创建JAR

    常春藤呢

    是的,像史蒂夫·洛夫兰这样的人会读到这个比较,并称其为犯规。他将讨论答案如何完全忽略了一个叫做常春藤的东西,以及Ant可以在最近的Ant版本中重用构建逻辑的事实。这是真的。如果你有一群聪明的人在使用Ant+antlibs+Ivy,你最终会得到一个设计良好、运行良好的构建。尽管如此,我非常相信Maven是有道理的,但我很乐意将Ant+Ivy与一个拥有非常敏锐的构建工程师的项目团队一起使用。话虽如此,我确实认为你最终会错过一些有价值的插件,比如Jetty插件,你最终会做很多你不需要做的工作

    比Maven vs.Ant更重要

    1. 就是使用存储库管理器来跟踪软件工件。我建议downloading Nexus。您可以使用Nexus代理远程存储库,并为您的团队提供一个部署内部构件的地方
    2. 软件组件有适当的模块化。一个大的单片组件很少随时间扩展。随着项目的发展,你会想要了解模块和子模块的概念。Maven非常适合这种方法
    3. 你在构建中采用了一些惯例。即使使用Ant,也应该努力采用与其他项目一致的某种形式的约定。当一个项目使用Maven时,这意味着熟悉Maven的任何人都可以选择构建并开始使用它运行,而不必仅仅为了弄清楚如何编译而对配置进行调整
  5. # 5 楼答案

    Maven是一个框架,Ant是一个工具箱

    Maven是一款预制的公路车,而Ant是一套汽车零件。有了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的长度是构建的3倍。xml,这是不偏离惯例的。事实上,我的Maven示例没有显示配置插件所需的额外54行代码。那个球。xml用于一个简单的项目。当您开始添加额外的需求时,XML真的开始显著增长,这对于许多项目来说并不常见

    但你必须告诉蚂蚁该怎么做

    我上面的蚂蚁例子当然不完整。我们仍然需要定义用于清理、编译、测试等的目标。这些目标在一个公共构建文件中定义,该文件由多模块项目中的所有模块导入。这让我想到,所有这些东西都必须在Ant中显式编写,而在Maven中却是声明性的

    的确,如果我不必显式地编写这些Ant目标,这将节省我的时间。但是有多少时间?我现在使用的通用构建文件是我5年前写的,从那时起只做了一些细微的改进。在我与Maven进行了两年的实验后,我把旧的Ant构建文件从壁橱里拿出来,掸掉灰尘,然后重新开始工作。对我来说,在5年的时间里,明确告诉蚂蚁该做什么的成本加起来不到一周

    复杂性

    我想提到的下一个主要区别是复杂性及其对现实世界的影响。Maven的目的是减少负责创建和管理构建过程的开发人员的工作量。为了做到这一点,它必须是复杂的。不幸的是,这种复杂性往往会否定他们的预期目标

    与Ant相比,Maven项目的构建人员将花费更多时间:

    • 阅读文档:关于Maven的文档要多得多,因为你需要学习的东西太多了
    • 教育团队成员:他们发现询问了解情况的人比自己寻找答案更容易
    • 解决构建问题:Maven不如Ant可靠,尤其是非核心插件。此外,Maven构建是不可重复的。如果你依赖于一个插件的快照版本,那么你的构建很可能会在没有任何更改的情况下崩溃
    • 编写Maven插件:在编写插件时,通常会考虑到特定的任务,例如创建webstart捆绑包,这使得在其他任务中重用插件或将其组合以实现目标变得更加困难。因此,您可能需要编写一个自己的插件来解决现有插件集中的漏洞

    相比之下:

    • Ant文档简洁、全面e和所有在一个地方
    • 蚂蚁很简单。一个试图学习Ant的新开发人员只需要理解几个简单的概念(目标、任务、依赖项、属性),就可以理解他们需要知道的其他内容
    • 蚂蚁是可靠的。在过去的几年里,Ant的发布并不多,因为它已经可以工作了
    • Ant构建是可重复的,因为它们通常是在没有任何外部依赖的情况下创建的,例如在线存储库、实验性第三方插件等
    • 蚂蚁很全面。因为它是一个工具箱,所以您可以组合这些工具来执行几乎任何您想要的任务。如果您需要编写自己的自定义任务,这非常简单

    熟悉

    另一个区别是熟悉度。新开发人员总是需要时间来跟上进度。在这方面,熟悉现有产品会有所帮助,Maven的支持者正确地宣称这是Maven的一个好处。当然,Ant的灵活性意味着你可以创建任何你喜欢的约定。所以我使用的惯例是将源文件放在一个名为src/main/java的目录中。我编译的类进入一个名为target/classes的目录。听起来很熟悉,不是吗

    我喜欢Maven使用的目录结构。我认为这是有道理的。还有他们的构建生命周期。所以我在我的Ant构建中使用相同的约定。这不仅是因为它有意义,而且是因为之前使用过Maven的人都会熟悉它

  6. # 6 楼答案

    Maven既是一个依赖关系管理工具(它可以用于从中央存储库或您设置的存储库中检索JAR),也是一个声明性构建工具。“声明式”构建工具与更传统的构建工具(如ant或make)之间的区别在于,您需要配置需要完成的内容,而不是如何完成。例如,可以在maven脚本中说,项目应该打包为WAR文件,maven知道如何处理这个问题

    Maven依赖于关于项目目录如何布局的约定,以实现其“声明性”例如,它有一个将主代码放在哪里、将网页放在哪里的约定。xml、单元测试等等,但也提供了在需要时更改它们的能力

    您还应该记住,maven中有一个用于运行ant命令的插件:

    http://maven.apache.org/plugins/maven-ant-plugin/

    此外,maven的原型使项目的启动速度非常快。例如,有一个Wicket原型,它提供了一个maven命令,您可以运行它来获得一个完整的、准备运行hello world类型的项目

    https://wicket.apache.org/start/quickstart.html