草庐IT

java - Ant 和 Maven 之间的差异

coder 2023-04-26 原文

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

7年前关闭。



Improve this question




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

最佳答案

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 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”、“从 . ...”等。在 Ant 必须明确说明过程的地方,Maven 有一些“内置”的东西,它只知道源代码在哪里以及应该如何处理。

高层对比

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

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

  • Ivy 呢?

    是的,所以像 Steve Loughran 这样的人会阅读这个比较并判罚犯规。他将谈论答案如何完全忽略称为 Ivy 的东西,以及 Ant 可以在最新版本的 Ant 中重用构建逻辑的事实。这是真实的。如果你有一群聪明的人使用 Ant + antlibs + Ivy,你最终会得到一个设计良好、有效的构建。尽管如此,我非常相信 Maven 是有道理的,我很乐意将 Ant + Ivy 与一个拥有非常敏锐的构建工程师的项目团队一起使用。话虽如此,我确实认为您最终会错过许多有值(value)的插件,例如 Jetty 插件,并且随着时间的推移,您最终会做大量不需要做的工作。

    比 Maven 与 Ant 更重要
  • 是您使用存储库管理器来跟踪软件工件。我建议 downloading Nexus .您可以使用 Nexus 来代理远程存储库,并为您的团队提供一个部署内部工件的地方。
  • 你有适当的软件组件模块化。一个大的单体组件很少随时间扩展。随着您的项目的发展,您将需要模块和子模块的概念。 Maven 非常适合这种方法。
  • 您为构建采用了一些约定。即使您使用 Ant,您也应该努力采用与其他项目一致的某种形式的约定。当一个项目使用 Maven 时,这意味着任何熟悉 Maven 的人都可以选择构建并开始运行它,而无需为了弄清楚如何让事物进行编译而摆弄配置。
  • 关于java - Ant 和 Maven 之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/603189/

    有关java - Ant 和 Maven 之间的差异的更多相关文章

    1. ruby - 将差异补丁应用于字符串/文件 - 2

      对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

    2. ruby-on-rails - Rails 应用程序之间的通信 - 2

      我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

    3. java - 等价于 Java 中的 Ruby Hash - 2

      我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

    4. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

      在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

    5. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

      我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

    6. java - 从 JRuby 调用 Java 类的问题 - 2

      我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

    7. java - 我的模型类或其他类中应该有逻辑吗 - 2

      我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

    8. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

      什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

    9. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

      这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

    10. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

      HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

    随机推荐