我鸣叫我认为有趣的技术内容,但是有趣的推文是获得最多参与的推文。我参加了3月的Javaland会议,偶然发现了Gradle Booth,发现了这颗宝石:
当然,在某个时候,一个狂热者劫持了线程,并声称是Gradle的所谓优越性。在这篇文章中,我想对我的立场提出一些启示,因此我可以指导人们去反复揭穿同样的“推理”。
要管理此问题,我需要及时回到。软件开发是一个快速变化的领域,我们的大部分理解都是基于个人经验。所以这是我的。
我的第一个构建工具:蚂蚁
我从2002年开始在Java开发。当时没有构建工具:我们通过IDE进行了编译和构建。为了记录,我首先使用Java的视觉时代;然后,我搬到了Borland Jbuilder。
用IDE构建有一个巨大的问题:每个开发人员都有专用的设置,因此人工制品的生成取决于开发人员机器的组合。
不可重复的版本是一个古老的问题。我对重复版本的第一个经验是Apache Ant:
Apache Ant是一个Java库和命令行工具,其使命是驱动构建文件中描述的进程作为目标和扩展点相互取决于彼此。蚂蚁的主要用法是爪哇应用的构建。蚂蚁提供许多内置任务,允许编译,组装,测试和运行Java应用程序。 ANT也可以有效地用于构建非Java应用程序,例如C或C ++应用程序。更一般而言,ANT可用于驾驶任何类型的过程,可以用目标和任务描述。
蚂蚁基于三个主要抽象:
- a 任务是一个原子单位,例如 - 框,但允许添加自定义。
- a target 是任务列表
- 您可以根据 compile 来定义任务之间的依赖关系,例如 package 。在这方面,您可以将ANT视为工作流执行引擎。
我很快在蚂蚁中变得“流利”。作为顾问,我从公司到公司,项目到项目。最初,我主要是建立蚂蚁,但是随着时间的流逝,蚂蚁变得更加普遍,我遇到了现有的蚂蚁设置。我的项目一直保持一致,但其他项目彼此不同。
每次到达新项目时,您都必须仔细阅读蚂蚁设置以了解自定义构建。而且,每个项目的结构都不同。有些将它们的来源放在src
中,有些在sources
中,有些在嵌套结构中等等。
我记得曾经有一个通用的构建文件,试图满足整个组织的项目需求。它定义了超过2,000行XML的80多个目标。我花了很多时间来了解如何在没有破坏项目的情况下对其进行调整的时间以及更多的时间来了解它。
。我的第二个构建工具:Maven
上述项目让我思考很多。我想改善这种情况,因为维护者已经推动了蚂蚁的限制。当时,我正在和我的朋友Freddy Mallet(Sonar Fame)合作。我们交谈,他指着我去了。我曾经用Maven建立了一个项目,但没有其他经验。我研究了该文档数小时,并通过弗雷迪(Freddy)的指导尝试通过反复试图将整个蚂蚁构建文件迁移到一个简单的父母pom。
在ANT中,您需要定义每个项目中的所有内容。例如,ANT需要配置Java文件位置以进行编译; Maven认为它们在src/main/java
之下,尽管可以覆盖它。 Maven确实用其惯例对Java构建领域进行了彻底改变方法。如今,许多软件默认提供了明智的配置。
对于像我一样从项目到项目的开发人员,这意味着加入新项目时的认知负担要少得多。我希望Java消息来源位于src/main/java
下。 Maven惯例超出了项目的结构。他们还定义了项目的生命周期,从编译到将工件上传到远程注册表中,通过单元和集成测试。
最后,初级开发人员倾向于对此有所了解,但是Maven定义了术语依赖管理。它介绍了人工制品注册机构的想法,可以从那里下载不可变的依赖项并将工件推向。在此之前,每个项目都必须将依赖性存储在其专用存储库中。
在记录中,对上述项目有几个存储的依赖性。当我从蚂蚁迁移到Maven时,我必须找到确切的依赖性版本。对于大多数人来说,它很简单,就像在文件名或罐子的清单中一样。但是,其中一个已通过其他课程进行了更新。这么多的不变性。
Maven对所有后来的构建工具都有深远的影响:他们指的是Maven。
没有我的构建工具:gradle
Gradle的主要主张是解决Maven的缺点,或者至少是这样认为的。尽管Maven不能免于责备,但Gradle认为最重要的问题是缺乏灵活性。这是一个令人惊讶的假设,因为这正是Maven比Ant的改善。 Maven项目具有相似的结构,并使用相同的生命周期:principle of least surprise实际上。相反,Gradle允许自定义几乎每个构建方面,包括生命周期。
在面对灵活性参数之前,让我承认Maven之后实现的两个伟大的原始Gradle功能:Gradle Daemon和Gradle包装器。
Maven和Gradle都是在JVM上运行的Java应用程序。就时间和资源而言,启动JVM是昂贵的。好处是,长期运行的JVM会随着时间的推移优化JIT-ED代码。对于短期任务,如果您考虑JVM启动时间,则收益为零,甚至有害。格拉尔(Gradle)提出了Gradle守护程序。当您运行Gradle时,它将寻找一个跑步的守护程序。如果没有,它将开始一个新的。命令行应用程序将把所有内容委派给守护程序。顾名思义,当命令行完成后,守护程序不会停止。守护程序利用了JVM的好处。
机会是您的应用程序会超过您当前的构建工具。当您需要从现在起五年后需要修复错误时,会发生什么,只是注意到项目的构建工具在网上无法使用? Gradle包装纸背后的想法是将确切的Gradle版本与项目一起保留,并且足够的代码可以通过Internet下载完整版本。作为副作用,开发人员无需在本地安装Gradle;所有人都使用相同的版本,避免任何差异。
揭露了丽格尔的灵活性
Gradle带来了Maven集成的两个上述优质功能,证明了竞争是良好的。尽管如此,我仍然没有发现Gradle的好处。
我将尝试将情感方面推开。一开始,Gradle Marketing试图在任何可能的场合放下Maven,发表疯狂的比较图表,并且通常是非常在其交流中的积极进取。假设这一阶段的持续时间远远超过了一家试图在市场上占有一席之地的年轻公司所接受的。您可以说,格拉尔(Gradle)的方法非常是俄狄浦斯(Oedipian):试图杀死其“父亲”的“父亲”。最后,在这些年之后,似乎已经明智了,现在“爱Maven”。
请记住,在Maven接管之前,每个蚂蚁项目都是临时的。 Maven确实结束了这一点。它将法律带到了定制项目的世界西部。您可以不同意法律,但这是法律,每个人都需要坚持下去。 Maven标准是如此根深蒂固,即使可以覆盖某些参数,例如,例如,源位置,也没有人做。
我确实遇到了Gradle灵活性的两个症状。我怀疑还有更多。
自定义生命周期阶段
Maven在四个阶段管理集成测试,按顺序运行:
-
pre-integration-test
:设置测试需要的任何东西 -
integration-test
:执行测试 -
post-integration-test
:清理资源,如果有的话 -
verify
:根据测试结果
我从来没有使用过前后的责任,因为每个测试都有专用的设置和拆卸逻辑。
在另一侧, gradle没有任何集成测试的概念。但是,Gradle Fanboys会很高兴地解释您可以添加所需的阶段。确实,Gradle允许生命周期“自定义”:您可以根据需要在常规生命周期中添加尽可能多的额外阶段。
这是一团糟,因为每个项目都需要提出所需的阶段数量及其名称:integration-test
,integration-tests
,integration-testing
,integration-testing
(对于懒惰)等。选项是无尽的。
雪花综合征
Maven将每个项目都视为常规标准项目。如果您有特定的需求,则可以为此编写插件。编写Maven插件绝对不好玩。因此,您只在必要时写一封,而不仅仅是因为您决定法律不适用于您。
Gradle声称缺乏灵活性是一个问题。因此,它想要修复它。我的依据相反:我的构建工具缺乏灵活性是一项功能,而不是错误。 Gradle使其容易入侵构建。因此,任何认为自己的项目是一种特殊的雪花,值得定制的人都会高兴地这样做。现实检查:很少情况;如果是的,则是用于框架,而不是常规项目。 Gradle支持者说,它仍然提供标准,同时允许简单的配置。这件事的核心是,如果可以在任何人的一时兴起,它都不是标准。
gradle是为Android项目的 de emave 构建工具。在我工作的一家公司中,有人在Gradle Build中编写了自定义Groovy代码,以运行声纳并将指标发送到内部声纳实例。当时没有开箱即用的声纳插件,否则我认为它没有切断它。到目前为止,一切都很好。
当另一个团队创建公司的第二个Android项目时,他们复制了第一个项目的结构和构建文件。目前,要做的聪明的事情就是用特定于声纳的代码制作内部Gradle插件。但是他们之所以没有这样做,是因为Gradle使构建构建变得如此容易。我是Gradle-Hater,我自己创建了插件。至少可以说,这可能是更好的开发人员体验。缺少高质量的文档并使用非构图(Groovy),我使用该控制台打印出对象的结构进行进展。
结论
竞争很好,而格拉尔(Gradle)带来了Maven集成,包装纸和守护程序的新想法。但是,Gradle的建立在于灵活性良好的前提下,而我的经验使我相反。蚂蚁非常灵活,从一个项目到下一个项目的认知负荷很高。
我们,开发人员是人类:我们想认为我们的项目与其他项目不同。大多数时候,它们不是。定制只是满足我们自我的一种方式。灵活的构建工具允许我们实施这种自定义,无论是否有必要。
无关紧要的自定义没有带来任何好处,而且易于发展,但维护昂贵。如果管理软件资产是我职责的一部分,我将始终选择稳定性而不是为我的构建工具而进行灵活性。
最初于8月6日在A Java Geek上发布 th ,2023