几年来,我一直很沮丧的基于java的构建工具项目。 在个人工做中,我看到几个Java项目和模块使用不一样的构建系统。 值得庆幸的是,我所见过的大多数项目都是创建在过去一年Maven或Gradle。 根据这一趋势,您只须要知道两个不一样的系统来了解项目的基本结构和依赖关系。 我不想给全部构建系统的概述,目前能够用于定义构建的一个基于Java的项目,我认为他们都很容易分裂成两个不一样的类型:java
目前,Maven和Gradle最著名的构建系统,他们每一个人的类型有关。 让咱们有一个更深的看着他们两人。编程
从个人观点来看,它是一个基于脚本的构建系统。 对于这样一个构建系统,您能够定义您本身的基于命令或一个API的任务。 在它,你能够编写自定义构建任务很容易使用Groovy。 它提供了一些基本的插件为共同构建Java项目的工做流程。 在此基础上,你不须要定义任何任务,像Java的编译为每一个项目来源,一遍又一遍。 可是因为它是基于任务,能够很容易地构建脚本中定义的,你没有任何结构或最佳实践应该如何定义结构构建脚本和应该如何定义信息,如项目名称或一个项目的依赖关系。 别误会个人意思:它提供了良好的api,但它是由开发人员决定在构建脚本,例如,定义项目的依赖关系。 此外,你老是须要运行构建脚本获得关于项目的信息。api
Maven在基于脚本的构建工具的功能很是有限。 全部的项目信息和如何构建它必须指定pom.xml文件。 在内部,您能够配置使用XML语法项目和构建。 全部的可能性,你必须配置项目的定义Maven在XSD文件。 经过这样作,很容易定义的静态元数据项目名称或项目描述。 甚至技术信息像groupId,artifactId、版本或静态依赖关系能够很容易地定义的。 经过使用Maven构建工具,您的项目将被创建一个最佳实践工做流程构建Java项目中定义的多个任务。 对于小项目来讲这是能够和api,可是若是你须要作一些特别的事情,你须要将插件添加到Maven。 这样一个插件必须定义为您的项目经过使用Maven的有限的XML语法。 这种插件必须的功能用Java编写的并提供了一个罐子。 大而复杂的项目,你须要几个永远结束在一个大的这些项目和读取XML文件做为描述和构建您的项目的定义。服务器
一点,值得庆幸的是,这两种方法的共同点是依赖性的方式将获得解决。 Maven和Gradle将下载(传递)从任何构件库的依赖关系。 Maven使用Maven中央这里做为默认Gradle用途JCenter。 此外,其余存储库(如私人公司存储库)能够很容易地定义的。 由于工件库遵循一些共同的标准,全部提到的存储库能够很容易地用于Maven或Gradle。编程语言
另外一方面,这两个工具/构建系统有一些大的缺点在我看来。 很容易在Maven中定义项目元数据和依赖关系,但这绝对是可怕的建立高度定制的构建与Maven。 若是你想建立asciidoc-based文档或上传最终工件到Java EE服务器。 你的POM文件很快就会变得不可读。 的Maven pom的Hazelcast项目例如,超过1000行。 理解一个1000行基于xml的新开发人员构建定义能够是很是使人沮丧的。 因此,Maven是漂亮的小模块和api,好比Apache commons或GSON。 开发人员能够快速地了解项目及其依赖项只需看看POM文件。 此外,工具不须要运行构建流程/脚本获取信息。 POM文件能够被解析。ide
Gradle,另外一方面,提供了很大的灵活性。 由于它是基于一个脚本,你能够作几乎一切,并支持自定义比Maven构建步骤要容易得多。 这很好若是你想要部署到服务器或建立你的工件,例如,文档。 但基于灵活性,构建脚本可能会变得复杂起来。 在大多数大型Java项目我已经看到在过去的几年里,只有少数开发人员知道如何改变它的构建。 此外,任何工具都须要运行Gradle构建项目的基本信息。 自从Gradle构建脚本是基于一种脚本语言,没法解析。 因此,最后,Gradle可悲的不是用于构建Java项目的完美的解决方案。工具
在此基础上,我想说,目前,没有Java构建工具是全部基于Java项目的完美的解决方案。 Maven太有限但伟大的小型项目,按照定义的Maven生命周期和定义。 Gradle,另外一方面,能够作你想作的一切,但甚至在其定义小型项目可能不一样,由于结构/能够定义您的构建描述以任何方式。 此外,您须要运行构建接收关于项目的信息。单元测试
基于这些观点,我认为,有一种方法的好处是简单的总和。 当有一个看构建系统JavaScript,你能够看到一个不一样。 现代JavaScript构建系统狼吞虎咽地吃、工做或多或少地喜欢它。 你能够很容易地定义您本身的自定义任务基于脚本语言。 此外,元数据中定义的项目一般是一个单独的文件中。 大多数项目,我看到过去的几个月里使用鲍尔定义项目的静态元数据。 这包括项目的描述(名称、描述、许可证等)及其依赖项。 构建工具像杯如今可使用鲍尔建造项目的信息(是的,这是一个很是简单的描述的内部流程)。 在此基础上,我问本身为何Gradle,例如,不能作一样的事情。 让咱们考虑一个静态定义Java项目和模块,能够很容易地集成到一个Gradle或Maven构建。 由于这样的定义将使用这两个工具都是开发人员轻松的学习如何阅读和使用这样一个静态的定义。 此外,工具不须要任何外部过程开始,像一个构建脚本,得到关于Java项目的信息。 对于完整的项目,您能够简单地建立自定义Gradle内部任务获得的全部信息的静态定义和重用它真正的创建。学习
下面,我将尝试素描这样的静态定义的样子和它如何可使用。测试
一个静态模块定义应该包含一个可读的描述模块。 这应该包括几个参数:
基于这个信息模块描述可能看起来像这样:
除了这些信息,一个项目须要一个唯一的标识符。 这能够很容易地定义的groupId artifactId,因此静态定义应该重用这些属性:
定义一个特定版本的一个项目,versionId应该添加。 基于这些信息,提供的一切Maven中央或JCenter被定义的模块。 此外,Maven pom。 xml能够很容易地建立基于这些信息,能够依赖这个模块和其余模块。 后添加的属性。 一个静态项目定义可能看起来像这样:
编译Java模块,咱们须要一些额外的信息。 我认为最基本的信息是源编码和应该用于编译的Java版本。 在这里,咱们须要指定一个Java版本定义所需的最低版本编译的来源和定义的Java版本,编译目标版本。 将这些信息添加到一个模块的描述可能会在如下文件:
基于这些信息,一个项目,不须要额外的类类路径中的下一个基本的Java类能够很容易地进行编译。 自完成模块定义中提供了一个静态方法,这能够很容易地集成到任何支持IDE或构建工具。
因为大多数项目取决于外部api和模块,静态模块定义应该提供信息模块的依赖关系。 像在Maven或Gradle,基于artifactId依赖项的定义,groupId,版本是最好的方法。 在编译、构建工具或IDE能够轻易下载从Maven中央或JCenter(传递)的依赖关系。 静态项目定义主要应该提供全部功能的Maven依赖的定义,但在大多数用例,简单地添加所需的依赖关系是全部你须要。 经过添加依赖关系信息,一个模块的定义是这样的:
ava模块定义为这样一个静态结构必须遵循的一些最佳实践和基本规则,从Maven和Gradle-based是众所周知的项目:
大家大多数人已经在使用Maven这样的构建工具,它,或者Ant来定义构建的Java项目。 我认为这是好的,应该使用在将来,。 尤为是当使用它,这是最新的构建工具所提到的,开发人员有这么多可能要建立一个自定义构建文件,一般每一个构建做品以不一样的方式,很难了解构建过程。 在全部这些文件中,关于构建过程的信息(好比一个构建脚本)和元数据的一个项目是混合。 经过封装从构建的元数据,这将是更容易获得一个模块或一个构建的整体概述。 此外,每一个构建文件或脚本取决于使用的构建系统。 这意味着开发人员老是使用Maven常常不能读或解释Gradle构建脚本。 tool-independent方式经过定义元数据,任何Java项目的开发人员能够理解的信息一旦他们至少有一个项目工做,提供静态元数据。 元数据不只为开发人员提供更好的可读性,但构建工具能够解释元数据提供支持。 经过这样作,全部的元数据文件的一部分的信息不该该被从新定义的构建脚本。 构建工具能够直接使用元数据文件中的信息来构建项目。 Gradle文件经过这样作,能够构建一个JAR文件基于静态元数据描述的模块:
这将是足够的编译全部的项目来源,运行全部单元测试,并构建一个JAR,他的名字叫artifactId和版本建立的元数据文件。
旁边的通用构建工具的ide能够提供支持的静态模块的元数据。 在这种状况下,您甚至不须要一个构建脚本。 基于的信息能够在元数据中定义,IDE能够下载所需的全部依赖项,编译项目的来源,并运行全部单元测试。 而这仅仅是开始。 基于这种方法,它能够扫描全部Java项目在GitHub,GitLab,BitBucket都找到一个模块的使用。
提供一个图形化的概述的传递依赖模块将容易,。 而不是运行Gradle创建接收信息的依赖,任何工具能够简单地解析静态元数据。 一个构建工具甚至没有安装。 构建工具和ide,其余工具如构建服务器将受益于这种方法。
曾经最重要的工具支持静态元数据,主要是全部Java项目的维护将变得更加容易。 方面喜欢定义的版本将只有一个焦点,和改变释放的版本将会很容易。
静态元数据并不适用于每一个项目。 一些项目须要在运行时生成的来源或动态依赖关系。 对于这类项目,静态元数据可能不足以编译项目。 但即便在这里,这样的元数据定义并非无用的。 可读元数据能够指定名称或许可和非动态的全部依赖项,这些元数据文件的一部分,。 这将结束在须要构建文件的代码,和工具,解释静态元数据至少能够处理项目描述的一个子集。 是的,这种方法目前没有可用的项目是基于另外一个编程语言,好比芬兰湾的科特林或Groovy。 但随着说:这只是一个初步的想法,我想要你的想法关于这个话题。