`
zljpp
  • 浏览: 259987 次
社区版块
存档分类
最新评论

Java Build工具Ant与Maven之比较

    博客分类:
  • java
阅读更多

没有一件东西能满足你的全部想法除非你自己创造一个出来。同样对于Build工具来说,也许最好的就是你自己写的。每个项目的Build过程都是独特的,而且通常你的项目要用多种方式构建。对Build工具的作者来说,设想每个构建的需求以迎合它基本是不现实的。工具最好就是提供一个灵活的库和可以重用的任务来被我们按需调用,但是这样也远远不够,成品的工具从来不会100%满足你的需求。你会浪费大量的时间让那些任务能按你的想法去工作,但是最后可能不得不自己写一个插件了事。写自己的定制化构建工具是快且容易的,比你担忧的维护量要少很多。构建就是要适合你的项目,而不是别的什么东西,这有什么可担心的。

 

如果你不想自己写构建工具,你可以用Rake。Rake是目前最好的基于Ruby语言编写的Java项目构建工具。Rake提供了一堆标准的方法来完成通常的构建任务,任何其他的任务都可以通过Ruby快速实现。Rake是用一个真正的程序语言(Ruby)来写构建脚本,这是它优于其它工具的地方。当然,Rake还有许多其它的优点,但都没有这个重要。

因此,你应该自己写构建工具,如果不想自己写,那就用Rake吧。如果你不想转向Rake,你也应该劝说他们转向正确的工具。假如技术上的决定被其它东西(办公室政?治)左右,假如不允许你这样做,那就离开这个项目,没什么好说的。

如果你没有勇气退出,那么使用Ant吧。对Java项目来说,Ant是第二好的构建工具。虽然不如Rake,Ant仍然可以说是最牛?B的构建工具。Ant成熟且稳定,快速且工具集丰富。Ant能让你把复杂的项目构建过程通过合身的脚本表达出来,虽然不全都是那么简单。

总而言之,写自己的构建工具,不行就转向Rake,不让转就力争或者辞职到其它让你用Rake的地方。如果全都不行,就用Ant吧,直到哪天有个公司使用Rake就跳过去。

就这些,这就是我能建议你们的唯一选择。因为,你们绝对不要、永远不要,在任何情况下试图使用Maven。

Maven的构建本身就是一个无穷无尽的绝望的怪圈,它一点一点地把你拖进万劫不复的Maven地狱。起初你就用了10分钟就搭好了Maven环境,你因此手舞足蹈。可是随着项目的进展,你的配置要增加,原来的pom.xml肯定是不够用了。为了让项目按你想要的方向上发展,你要一点点地增加配置。用不了多久,你就会第一次鬼打墙般地遇到问题。(用“鬼打墙”这个词,我的意思是“突然搞得人很头疼”。之所以说“第一次”,因为将来你还会不断地鬼打墙)。终于有一天,你会为了解决一个燃眉之急而临时凑合地改了改这个已经乱的不成样子的pom.xml。你可能还对Maven满意了好一阵子...直到又有一个问题露出了恶心的小头(这让我想起女孩青春期挤脸上粉刺的情景。当她挤掉脸上出现的第一个粉刺豆豆,她会好有成就感。可是当豆豆越来越多,挤也挤不干净的时候,她就不再对少女时期洁白无瑕的脸庞抱有幻想了——译者注)。这让我联想到希腊神话里的悲剧,你就是被打入地狱的灵魂,带着永世的诅咒——你的基于Maven的构建过程。

严肃地说,Maven就是坏主意的糟透了的实现。我相信总是有人认为Maven即使不性感,起码也够清晰智能,可是,现实上Maven的实现毫无这些迹像。实际上,Maven是彻头彻尾地糟透了,已经成为了一个著名的反例——告诉人们如何不要去构建软件。当构建正在以Maven相反的方式工作,你知道这是多么的可怕。

例如从Maven's Surefire 插件输出的测试结果。(Surefire插件用来在Maven构建生命周期的测试阶段执行一个应用的单元测试。它会产生两种不同形式的测试结果报告:纯文本;.xml文件。默认情况下,这些文件生成在工程${pom文件所在的目录}/target/surefire-reports目录下。——译者注)。只要测试通过一切万事大吉,但是如果出了错误,Surefire的测试报告就是一个调试的梦魇。只有失败的测试类的名称被记录下来。你必须手动地查看target/surefire-reports/目录下的日志文件,这些日志文件是按每个测试类组织的。如果多个测试类都失败了,你就必须分别地检查多个日志文件。看上去是个小事情,累积起来会让人一肚子怨气,从而生产效率下降。

Maven主张的约定优于配置,其实是个谎言。Maven支持的唯一约定是:编译,运行单元测试,生成jar包。做其它任何事情就开始要配置了:生成war包?要配置;从命令行运行程序?要配置;运行验收测试(把所有系统理论上目前支持的场景都列出来,然后按功能分类测试,如果测试成功,就在此场景中标明“成功”,否则,就标明“失败”。——译者注)或功能测试或性能测试,还是要配置它,但是涉及到不能运行你的单元测试,或者在常规的单元测试阶段不能运行。想要生成项目的代码覆盖率度量?你还要配置,但是你的测试要运行2次(或者可以只运行一次,只是不能在常规的单元测试阶段);尽管是做全方位的测试,它还是经常会报告了0%的代码覆盖率。

谈到配置,Maven的配置语法是Sendmail(在Unix系统的用户中,Sendmail是应用最广的电子邮件服务器。Sendmail作为一种免费的邮件服务器软件,已被广泛的应用于各种服务器中,它在稳定性、可移植性、健壮性等方面很出色。)以来最让人反胃的了——交替正常格式的XML。因此,Maven配置累赘,拗口,难写。在Ruby、Rake的XML或者Ant中1、2行就可以搞定的事情,在pom.xml里要6、7、8行才可以做到(还要假设Maven能做到才行)。

Maven的配置一点也不连贯。一会引用classpath的相对路径,一会用相对于磁盘的绝对路径,一会又用运行于JVM之上的Maven的系统属性。有些绝对路径能被移植是因为Maven知道怎么自动纠正错误,有些纠正不了。有时Maven智能地知道如果递归地构建项目,有时经常又不行。

而且,有些东西在pom中根本无法配置。比如:Maven仓库、服务器、授权凭据等是在settings.xml配置的。既然pom.xml要提交到项目的版本控制仓库,那么Maven把用户密码置于pom.xml文件之外是言之有据的。可是Maven的解决方法太恐怖了:所有的这类配置被放进了一个叫做settings.xml的文件里,而这个文件不在任何的项目目录里。你不能直接地在桌面电脑和笔记本、其它开发者或者你的项目构建服务器之间共享任何这类配置。但是,它却自动地在你工作的每个单独的Maven项目间共享,潜在地在同一台计算机上的不同用户之间的每个Maven项目间共享。当一个新的开发者加入到项目中,就必须手动合并必要的配置信息到原有的settings.xml中。当一个新的代理被加到构建服务器里,还是要手动合并必要的配置信息到原有的settings.xml中。同上,当你迁移到新的机器。任何这些配置需要更新,必须手动地在每个单独的机器上更新。这也是一个在Maven到来之前就已经解决的问题:属性文件。项目组把通用的属性文件提交到版本控制,然后每个开发者在本地的属性文件中覆盖这些信息,本地的属性文件中不提交到版本控制。

所有这些东西在Maven里——那些约定,配置,过程——被以所谓的Maven方式管理。不幸的是,所谓的Maven方式没有文档说明。为了抓住那一定点儿稍纵即逝的信息,往往要在Maven文档里拉网式地搜索,Google,或者买Maven开发者们写的书。(有点类似众里寻她千百度,蓦然回首,不知春归处——译者注)。还有的另外办法来找到所谓的Maven方式就是鬼打墙了。(走着走着被自己要找的东西绊倒了。作者的意思就是这——所谓的Maven方式——就像看不见的边界,试图找到它的办法可能就是不经意地撞到它——译者注)。Maven的构建不是为了灵活,不支持每种可能的构建过程。Maven是为了Apache项目而构建的,假定了每个项目的构建过程都像Apache项目自身一样。这对自愿奉献自己时间的开源库的开发者来说是个好消息,对于这些人,“发布”意味着“上传一个新的zip文件到你的站点为了便于其他人手动发现,下载然后添加到他们自己的项目中。” 其实这是溜须拍马的做法。Rake和Ant可以适应每种构建过程,Maven不能;Maven也许,实际上很可能,它恰恰不能支持你想要的那种构建软件的方式。

还有就是Maven的依赖管理是彻头彻尾地不可挽回的破坏。事实上,我收回我的话;Maven的下载ibiblio(Maven会从ibiblio.org中的公用仓库中同步构件,这个公用仓库下载缓慢、 不稳定,并且不包含一些构件的最新版本,而且不能上传团队私有的构件。——译者注)到用户的home目录,然后一古脑地把所有东西像垃圾一样倒在classpath下。这种傻到让人难以置信的依赖管理策略是极其错误的,从来不应与“依赖管理”混淆。我近来工作的一个Maven工程,它产生出一个51MB的.war文件;当我把它转到Ant下手动配置依赖管理,这个.war文件减小到了17MB。靠,51-17=34=17x2,居然原来三分之二的东西都是Maven给我们制造的无用的废物。

不相干的依赖包不仅仅吃掉硬盘空间,而且会吃掉宝贵的内存。Maven完全就是多吃多占内存的大蠢猪。相对简单的项目,只带有一个父pom和一些子模块,就要求一大堆的JVM内存——通过改变JAVA_OPTS配置来得到,而这些精巧的JAVA_OPTS配置通常你仅仅在产品服务器上才用到。如果整合Maven构建工具到你的IDE,事情可能更糟。它把JVM的最大堆尺寸设成好几百兆,把最大的PermGen尺寸设成几百兆,并启用permgen sweeping,这样类自己会被垃圾回收。(PermGen——Permanent Generation space,是指内存的永久保存区域。这一部分用于存放Class和Meta的信息,Class在被Load的时候被放入PermGen区域,它和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen进行清理,所以如果你的APP会Load很多Class的话,就可能出现PermGen错误。——译者注)。所有这一切仅仅是构建你的项目,或者在IDE里与Maven一起工作。

一个可笑的故事:在上面那个项目里,我曾经经历了一个10分钟的“mvn clean”构建命令,因为Maven愚蠢地想在“rm -rf ./target/”之前做点事情 (参考类似的例子: http://gist.github.com/267553)。实际这个故事一点不可笑;相信我,你不想要一个工具——它在清空你的构建输出目录之前自动下载所有未解析的依赖包。你不想要一个工具——它自动下载所有未解析的依赖包。隔一段时间就下载所有未解析的依赖包让你的构建过程变得不确定。好,我是不确定主义者:这在学校里好玩,不是在工作中。

所有那些不必要的,不想要的网络来回占有了大量时间。每一次构建你都要为Maven的破坏性的包依赖管理付出性能的代价。10分钟的clean构建是恐怖的,但是每次构建都多几分钟就更糟了。我估算的每次构建的平均额外消耗时间大约是一分钟,这是基于一个事实:我把Maven项目迁移到Ant上,平均构建时间缩短了2.5分钟到1.5分钟;类似地把Ant项目迁移到Maven上,平均构建时间增长了2~3分钟。

你无法控制,也看不清哪些包被哪些包指定。构建可能中断因为不同的Maven版本在不同的时间会下载不同的包。你的本地构建有一天也会中断,当你的依赖包的依赖包偶然地发布了新的,不向后兼容的改变而忘记了敲上版本号;那些失败是无辜的。更容易发生的情况是你的项目A依赖了某个特定版本的其它项目B,而这个项目B反过来依赖某个最后版本的另外的项目C,这时你还蒙在鼓里,即使下游包提供者敲上了正确的版本号。每次发布依赖包的依赖包都可能造成新的错误,从而会浪费你几个小时去追踪为何构建失败。

但是Maven比这甚至还要糟的是:Maven不仅仅解决你的项目的包依赖,它还自动解决自己带的插件的包依赖。于是现在你不仅仅要担心不同的Maven实例偶然会下载不兼容的东西(或者同一个Maven在不同的时间下载不同的东西),你还要担心你的构建工具在不同计算机的不同时间上的行为不一致。

Maven的残缺不堪的包依赖管理同时带来了一个安全的隐患,既然Maven目前不可能确定包最初来自哪里,被篡改与否。当上传包到代码仓库中,包会被自动数字签名,当Maven下载包时会自动验证签名,可是Maven无疑地信任代码仓库中的签名。当前Maven的包安全是由Maven开发者控制的,他们有对ibiblio权威信息库写的权限。但是无法知道你下载的包的所有依赖包的代码仓库是不是中毒了,没有办法知道你的本地仓库缓存是不是中毒了,也无法知道你本地仓库缓存中里的包来自哪里和谁上传了它们。

综上问题并不是粗心的程序员造成的,也无法通过仓库管理员锁定每个Maven需要的包来解决。如果Maven假设人从来不犯错误,那它就是一个破烂货(Maven is broken and wrong)如果Maven要使用者明确指定每个依赖的版本,每个依赖的依赖,来减少下载不兼容的包的可能性,那它就是一个破烂货。如果Maven非得通过一个第三方工具来阻止它连接到网络并自动下载那些乱七八糟的狗?屎,那它就是一个破烂货。如果Maven无视每次构建都要连接到网络,为任何更新都检查每个依赖项,然后自动下载它们,从而让构建过程变得缓慢不堪,那它就是一个破烂货。如果Maven在我的办公室和家里的笔记本电脑上表现的不一致,那它就是一个破烂货。如果Maven连删除一个目录都需要互联网,那它就是一个破烂货。Maven就是一个破烂货。

分享到:
评论
1 楼 yszy 2012-06-01  
一直以为只有我反感Maven,没想到知音还挺多。开源的工具太多了,多到学不完,一直无法理解为什么要把简单的事情变得这么复杂。Maven看着貌似很牛逼,其实带来的是无穷无尽的痛苦,都是浮云!一切都是浮云,java、javac、jar......简单命令搞定一切,零学习成本。简单就是最好的!

相关推荐

    Maven 与 Ant 之比较

    标题“Maven 与 Ant 之比较”表明了本文将探讨两种在Java开发中广泛使用的构建工具——Maven和Ant。它们的主要功能是管理和自动化项目的构建过程,包括编译源代码、运行测试、打包应用以及部署。通过对两者进行对比...

    Maven build之pom.xml文件中的Build配置

    Maven是Apache软件基金会中的一个项目,它是一个项目管理工具,主要用于Java项目的构建、文档生成、报告和依赖管理。Maven通过一个叫做pom.xml的项目对象模型文件来配置项目构建的各个方面,其中<build>标签是Maven...

    JAVA网上会议系统开源源码(采用Ant和Maven管理)

    Ant是Apache软件基金会的一个项目,它是Java应用的构建工具,主要通过XML格式的构建文件(build.xml)来定义构建任务。Ant的优点在于灵活性高,可以根据项目需求自定义构建过程,但缺点是配置较为繁琐,对于大型项目...

    Maven2.Ant.Junit合集

    《Maven2.Ant.Junit合集》是一个包含多种IT工具和框架的资源包,主要聚焦于Java开发中的构建管理和单元测试。这个合集提供了PDF和CHM两种格式的文档,便于不同用户根据个人喜好进行阅读。以下是这些工具及其重要知识...

    Java构建工具之Ant

    Java构建工具之Ant 在Java开发中,构建工具起着至关重要的作用,它们负责自动化编译、测试、打包和部署等任务。Ant是Java社区早期广泛使用的构建工具之一,由Apache软件基金会开发,以XML为基础,提供了一种跨平台...

    Java的Build工具—Ant应用指南(1)

    Java的构建工具Ant是Apache软件基金会的一个开源项目,它是一个...同时,随着持续集成和持续部署(CI/CD)理念的普及,Ant也可以作为这些流程的一部分,与其他工具如Maven、Gradle协同工作,为Java开发提供强大的支持。

    Java.构建工具.ANT

    【Java 构建工具 ANT】是Java开发中的一个重要组成部分,它是Apache软件基金会开发的一个开源构建工具,主要用于自动化Java项目的构建、编译、测试和部署等任务。Ant以其灵活性和可扩展性著称,通过XML配置文件...

    Ant最新版 build工具

    Ant是Apache软件基金会开发的一款基于Java的构建工具,它的全称是Apache Ant。...虽然现在有其他如Maven和Gradle等更先进的构建工具,但Ant仍然在Java开发领域占有一定的地位,特别是在需要高度定制化的项目中。

    Java Development with Ant.pdf

    - Ant与其他构建工具(如Maven、Gradle)的比较 - 在大型项目中引入Ant的优点与挑战 - 如何优化Ant构建脚本以提高效率 10. **扩展Ant的核心任务** - 自定义任务的实现方法 - 使用第三方插件增强Ant的功能 - ...

    java的Ant打包工具

    Java的Ant打包工具是开发过程中不可或缺的一部分,尤其在构建、部署和自动化任务管理方面发挥着重要作用。Ant是由Apache软件基金会开发的一个开源项目,其设计灵感来源于Make,但使用XML来描述构建过程,使得构建...

    JAVA ANT包发布工具包

    Java ANT包发布工具包是Java开发中的一个重要组件,主要用于构建和自动化Java项目。...同时,ANT与其他Java工具,如JUnit(单元测试)、Maven(项目管理)等,可以很好地协同工作,构建出完整的Java开发环境。

    maven ant thrift0.9.0

    标题 "maven ant thrift0.9.0" 涉及到的是三个关键的软件开发工具:Thrift 0.9.0、Apache Ant 和 Apache Maven。这些工具在Java和其他编程语言的开发环境中广泛使用,特别是在构建和部署分布式系统时。 Thrift ...

    ant工具ant资源包

    Ant由于其灵活性和广泛的社区支持,被广泛应用于Java项目中,与Maven和Gradle等现代构建工具一起,构成了Java开发者的重要工具链。虽然Maven和Gradle在某些方面提供了更高级的功能,但Ant仍然是很多老项目和特定场景...

    java项目ant打包脚本

    综上所述,`java项目ant打包脚本`是Java开发过程中不可或缺的一部分,它通过Ant工具和`build.xml`配置文件实现了项目的自动化构建,提高了开发效率并确保了构建的一致性。理解并熟练掌握Ant打包脚本的编写和使用,...

    Ant_的最完整build.xml解释,Ant入门与进阶

    五、Ant与Maven的比较 虽然Ant提供了高度的灵活性,但随着项目的复杂性增加,配置文件可能变得难以维护。相比之下,Maven通过约定优于配置的原则简化了项目构建,使用预定义的生命周期和插件,使得大部分项目构建...

    java Ant工具电子书,pdf格式

    8. **Ant与Maven的对比**:虽然Ant是早期的构建工具,但随着Maven的流行,两者间的比较和选择也是重要的话题。书中可能涉及它们的异同和应用场景。 9. **实战应用**:除了理论知识,书中还会提供实际项目案例,教你...

    ant工具和ant教程

    Ant以其XML为基础的构建文件(build.xml)而著名,这些文件详细描述了如何编译、打包和测试Java应用程序。Ant的核心理念是“一切都是任务”,它通过预定义的任务和用户自定义的任务来执行各种构建操作。 在Ant教程...

    ant的build文件说明

    Ant也很好地与Maven和Gradle等现代构建工具集成,使得迁移和协作更加便捷。 总的来说,Ant的build文件是项目构建的核心,它通过XML格式定义了构建过程的各个步骤,包括编译、测试、打包等,同时允许开发者根据项目...

Global site tag (gtag.js) - Google Analytics