目录
从Apache Maven迁移构建
💡患有缓慢的Maven构建? 在此处注册以参加我们的构建缓存培训课程,以了解Gradle Enterprise如何将Maven构建速度提高多达90%。
Apache Maven是用于Java和其他基于JVM的项目的构建工具,这些项目已被广泛使用,因此想要使用Gradle的人们经常不得不迁移现有的Maven构建。本指南将通过解释这两种工具的模型之间的差异和相似之处,并提供简化步骤可以帮助您进行迁移。
转换构建可能会很吓人,但您不必一个人做。您可以从help.gradle.org搜索文档,论坛和StackOverflow,或者在遇到麻烦时访问Gradle社区。
进行迁移
Gradle和Maven之间的主要区别是灵活性,性能,用户体验和依赖性管理。Maven与Gradle功能比较中提供了这些方面的直观概述。
从Gradle 3.0开始,Gradle投入了大量资金,以使Gradle的构建速度更快,并具有诸如构建缓存,避免编译和改进的增量Java编译器等功能。对于大多数项目,即使不使用构建缓存,Gradle的速度也比Maven快2-10倍。可以在此处找到有关从Maven切换到Gradle的深入性能比较和业务案例。
一般准则
对于如何构建项目,Gradle和Maven有着根本不同的看法。Gradle提供了一种灵活且可扩展的构建模型,该模型将实际工作委托给任务依赖关系图。Maven使用固定的线性阶段模型,可以在其中附加目标(完成工作的事物)。这可能会使两者之间的迁移看起来令人生畏,但迁移可能出奇的容易,因为Gradle遵循许多与Maven相同的约定(例如标准项目结构) ,并且其依赖项管理以类似的方式工作。
在这里,我们列出了一系列步骤供您遵循,这将有助于促进将任何Maven构建移植到Gradle:
💡并排保留旧的Maven构建和新的Gradle构建。您知道Maven构建可以工作,因此您应该保留它,直到您确信Gradle构建可以生成所有相同的工件,然后再做您需要的事情。这也意味着用户可以在不获取源树的新副本的情况下尝试Gradle构建。
-
构建扫描将使可视化您现有Maven构建中发生的事情变得更加容易。对于Maven构建,您将能够查看项目结构,正在使用的插件,构建步骤的时间表等等。保持方便,以便可以将其与转换项目时获得的Gradle构建扫描进行比较。
-
开发一种机制来验证两个构建产生相同的工件
这是确保您的部署和测试不中断的至关重要的一步。即使是很小的更改,例如JAR中清单文件的内容,也会引起问题。如果您的Gradle构建生成的输出与Maven构建生成的输出相同,则这将使您和其他人对切换充满信心,并使更容易实施将带来最大收益的重大更改。
这并不意味着您需要在每个阶段都验证每个工件,尽管这样做可以帮助您快速确定问题的根源。您可以只关注关键输出,例如最终报告以及已发布或部署的工件。
与Maven相比,您需要考虑Gradle产生的构建输出中的某些固有差异。生成的POM将仅包含消耗所需的信息,并且它们将针对该场景正确使用
<compile>
和确定<runtime>
范围。您可能还会看到归档文件中的文件顺序和类路径中的文件顺序不同。大多数差异将是良性的,但值得识别它们并验证它们是否正确。 -
这将创建您需要的所有Gradle构建文件,即使对于多模块构建也是如此。对于更简单的Maven项目,Gradle构建将可以运行!
-
构建扫描将使可视化构建中的事情变得更加容易。对于Gradle构建,您将能够查看项目结构,依赖关系(常规和项目间的依赖关系),正在使用的插件以及构建的控制台输出。
此时您的构建可能会失败,但这没关系;扫描仍将运行。将Gradle构建的构建扫描与Maven构建的构建扫描进行比较,然后继续执行此列表以排除故障。
我们建议您在迁移期间定期生成构建扫描,以帮助您确定问题并排除故障。如果需要,您还可以使用Gradle构建扫描来确定提高构建性能的机会,毕竟,性能首先是切换到Gradle的主要原因。
-
通过配置额外的源集,可以简单地迁移许多测试。如果您使用的是第三方库(例如FitNesse),请查看Gradle Plugin Portal上是否有合适的社区插件。
-
用Gradle等效项替换Maven插件
对于流行的插件,Gradle经常有一个等效的插件供您使用。您可能还会发现可以用内置的Gradle功能替换插件。作为最后的选择,您可能需要通过自己的自定义插件和任务类型重新实现Maven插件。
本章的其余部分更详细地介绍了将构建从Maven迁移到Gradle的特定方面。
了解构建生命周期
Maven构建基于构建生命周期的概念,该概念由一组固定阶段组成。这可能会成为用户迁移到Gradle的障碍,因为它的构建生命周期有所不同,尽管了解Gradle的构建方式如何适合初始化,配置和执行阶段的结构很重要。幸运的是,Gradle的功能可以模仿Maven的各个阶段:生命周期任务。
这些使您可以通过创建仅依赖于您感兴趣的任务的无操作任务来定义自己的“生命周期”。并且为了使Maven用户更轻松地过渡到Gradle,Base插件 -由所有JVM语言应用Java库插件之类的插件 —提供了一组与主要Maven阶段相对应的生命周期任务。
这是一些主要的Maven阶段以及它们映射到的Gradle任务的列表:
clean
使用clean
基本插件提供的任务。
compile
使用Java插件和其他JVM语言插件classes
提供的任务。这将编译所有语言的所有源文件的所有类,并通过processResources任务执行资源过滤。
test
使用Java插件提供的test
任务。它仅运行单元测试,或更具体地说,运行组成test
源集的测试。
package
使用基本插件提供的assemble
任务。这将构建适合项目的任何软件包,例如Java库的JAR或传统Java Webapp的WAR。
verify
使用基本插件提供的check
任务。这将运行附加到它的所有验证任务,通常包括单元测试,任何静态分析任务(例如Checkstyle)以及其他任务。如果要包括集成测试,则必须手动配置这些,这是一个简单的过程。x
install
使用Maven发布插件提供的publishToMavenLocal
任务。
Gradle还允许您解析对本地Maven缓存的依赖关系,如“声明存储库”部分中所述。
deploy
使用Maven Publish插件提供的publish
任务 - 如果您的构建正在使用该Maven插件,请确保选择旧的Maven插件(ID: maven
)。这会将您的程序包发布到所有已配置的发布存储库。即使定义了多个存储库,也有其他任务可以使您发布到单个存储库。
请注意,默认情况下,Maven Publish Plugin不发布source 和 Javadoc JARs ,但是可以按照构建Java项目的指南中的说明轻松激活它。
执行自动转换
Gradle的init
任务通常用于创建新的骨架项目,但是您也可以使用它将现有的Maven构建自动转换为Gradle。将Gradle安装到系统上后,只需执行以下命令
> gradle init
从根项目目录中,让Gradle做它的事情。这基本上包括解析现有的POM并生成相应的Gradle构建脚本。如果您要迁移多项目版本, Gradle还将创建一个设置脚本。
您会发现新的Gradle构建包括以下内容:
-
POM中指定的所有自定义存储库
-
您的外部和项目间依赖性
-
用于构建项目的适当插件(仅限于Maven Publish,Java和War插件中的一个或多个)
有关自动转换功能的完整列表,请参见Build Init插件一章。
要记住的一件事是程序集不会自动转换。它们不一定要转换,但是您将需要做一些手工工作。选项包括:
-
使用分发插件
-
使用应用程序插件
-
从Gradle插件门户使用合适的社区插件
如果您的Maven构建没有很多插件或以自定义方式提供很多插件,则只需运行
> gradle build
迁移完成后。这将运行测试并产生所需的工件,而您无需任何额外的干预。
迁移依赖项
Gradle的依赖项管理系统比Maven的依赖项管理系统更灵活,但它仍支持相同的存储库,声明的依赖项,范围(Gradle中的依赖项配置)和可传递依赖项的概念。实际上,Gradle与兼容Maven的存储库完美配合,这使得迁移依赖关系变得容易。
✨两种工具之间的显着区别是它们如何管理版本冲突。Maven使用“最接近”的匹配算法,而Gradle选择最新的匹配算法。不过,请放心,您可以控制选择哪个版本,如管理传递依赖项中所述。
在以下各节中,我们将向您展示如何迁移Maven构建的依赖管理信息中最常见的元素。
声明依赖
Gradle使用与Maven相同的依赖项标识符组件:group ID, artifact ID ,version。它还支持分类器。因此,您需要做的就是将标识符的依赖项信息替换为Gradle的语法,这在“声明依赖项”一章中进行了介绍。
例如,考虑对Log4J的这种Maven风格的依赖关系:
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
在Gradle构建脚本中,这种依赖关系如下所示:
例子1.声明一个简单的编译时依赖
Groovy
build.gradle
dependencies {
implementation 'log4j:log4j:1.2.12' // (1)
}
Kotlin
build.gradle.kts
dependencies {
implementation("log4j:log4j:1.2.12") // (1)
}
1.将Log4J的1.2.12版附加到implementation
配置(作用域)
字符串标识符采用的Maven的值groupId
,artifactId,
version
,虽然Gradle指它们作为group
,module
和version
。
上面的示例提出了一个明显的问题:该implementation
配置是什么?它是Java插件提供的标准依赖项配置之一,通常被用来替代Maven的默认compile
范围。
Maven的作用域和Gradle的标准配置之间的几个区别归结为Gradle区分了构建模块所需的依赖项和构建依赖于该模块的模块所需的依赖项。Maven没有这种区别,因此已发布的POM通常包括库的使用者实际上不需要的依赖项。
以下是主要的Maven依赖范围以及如何处理它们的迁移:
compile
Gradle有两种配置可以代替compile
范围使用:implementation
和api
。 前者适用于所有应用Java插件的项目,而api
仅适用于专门应用Java库插件的项目。
在大多数情况下,您应该只使用implementation
配置,尤其是在构建应用程序或webapp时。 但是如果您要构建库,则可以在构建Java库的部分中了解使用api
声明哪些依赖项。 上面链接的Java库插件一章提供了有关api
和implementation
之间区别的更多信息。
runtime
使用runtimeOnly
配置。
test
Gradle区分了compile 项目测试所需的那些依赖项和仅运行它们所需的那些依赖项。
应针对testImplementation
配置声明测试编译所需的依赖关系。仅运行测试所需的那些应该使用testRuntimeOnly
。
provided
使用compileOnly
配置。
请注意,War Plugin添加providedCompile
和providedRuntime
依赖项配置。它们的行为compileOnly
与WAR文件中的行为略有不同,并且仅确保这些依赖项未打包。但是,依赖项包含在运行时和测试运行时类路径中,因此如果您需要这种行为,请使用这些配置。
import
该import
范围主要在<dependencyManagement>
块内使用,并且仅适用于仅POM的出版物。阅读有关使用物料清单的部分,以了解有关如何复制此行为的更多信息。
您还可以指定对仅POM的发布的常规依赖性。在这种情况下,在该POM中声明的依赖关系将被视为构建的常规传递依赖关系。
例如,假设您要使用 groovy-all
POM进行测试。这是仅POM的出版物,在<dependencies>
块内列出了自己的依赖性。Gradle构建中的适当配置如下所示:
示例2.Consuming a POM-only依赖项
Groovy
build.gradle
dependencies {
testImplementation 'org.codehaus.groovy:groovy-all:2.5.4'
}
Kotlin
build.gradle.kts
dependencies {
testImplementation("org.codehaus.groovy:groovy-all:2.5.4")
}
这样的结果将是将POM 中的所有compile
和runtime
范围依赖项groovy-all
添加到测试运行时类路径,而仅将compile
范围依赖项添加到测试编译类路径。与其他作用域的依赖关系将被忽略。
声明存储库
Gradle允许您从任何与Maven兼容或与Ivy兼容的存储库中检索已声明的依赖项。与Maven不同,它没有默认存储库,因此您必须声明至少一个。为了具有与Maven构建相同的行为,只需在Gradle构建中配置Maven Central,如下所示:
示例3.将构建配置为使用Maven Central
Groovy
build.gradle
repositories {
mavenCentral()
}
Kotlin
build.gradle.kts
repositories {
mavenCentral()
}
您还可以使用该repositories {}
块来配置自定义存储库,如“存储库类型”一章中所述。
最后,Gradle允许您解决对local Maven cache/repository依赖关系。这有助于Gradle构建与Maven构建进行互操作,但是如果您不需要这种互操作性,则不应使用该技术。如果要通过文件系统共享已发布的工件,请考虑使用 file://
URL 配置自定义Maven存储库。
您可能还对了解Gradle自己的依赖项缓存感兴趣,后者比Maven的行为更可靠,并且可以被多个并发的Gradle进程安全地使用。
控制依赖项版本
传递依赖项的存在意味着您可以轻松地在依赖关系图中最终获得同一依赖项的多个版本。默认情况下,Gradle将选择图中的依赖项的最新版本,但这并不总是正确的解决方案。这就是为什么它提供了几种机制来控制解决给定依赖项的哪个版本的原因。
在每个项目的基础上,您可以使用:
在控制传递依赖项一章中列出了更多专门的选项。
如果要确保多项目构建中所有项目的版本一致性,类似于<dependencyManagement>
Maven中的块的工作方式,则可以使用Java Platform Plugin。这使您可以声明一组可以应用于多个项目的依赖关系约束。您甚至可以将平台发布为Maven BOM或使用Gradle的元数据格式发布。有关如何执行此操作的更多信息,请参见插件页面,尤其是在使用平台部分,以了解如何将平台应用于同一构建中的其他项目。
排除传递依赖
Maven构建使用排除项将不需要的依赖关系或不需要的依赖关系版本排除在依赖关系图中。您可以使用Gradle做同样的事情,但这不一定是正确的事情。Gradle提供了其他选项,这些选项可能更适合给定的情况,因此您确实需要了解为什么存在排除项才能正确迁移它。
如果您出于与版本无关的原因而要排除依赖项,请查看dependency_downgrade_and_exclude.html的部分。它显示了如何将排除项附加到整个配置(通常是最合适的解决方案)或依赖项。您甚至可以轻松地将排除应用于所有配置。
如果您对控制实际解决依赖关系的版本更感兴趣,请参阅上一节。
处理可选的依赖
关于可选依赖项,您可能会遇到两种情况:
-
您的某些传递依赖项被声明为可选
-
您想在项目的已发布POM中将某些直接依赖项声明为可选
对于第一种情况,Gradle的行为与Maven相同,只是忽略了声明为可选的任何传递依赖。如果相同的依存关系在依存关系图中的其他位置显示为非可选,则无法解析它们并且对所选版本没有影响。
至于将依赖项发布为可选的,Gradle提供了一个更丰富的模型,称为Feature Variants,它可以让您声明库提供的“可选功能”。
使用物料清单(BOM)
Maven允许您通过在<dependencyManagement>
打包类型为的POM文件的一部分内定义依赖项来共享依赖项约束pom
。然后可以将这种特殊类型的POM(物料清单)导入其他POM中,以便在项目中拥有一致的库版本。
Gradle可以通过基于 platform() 和 enforcedPlatform() 方法的特殊依赖项语法,将此类BOM用于相同的目的。您只需以常规方式声明依赖项,然后将依赖项标识符包装在适当的方法中,如“imports” Spring Boot Dependencies BOM 的示例所示:
例子4.在Gradle版本中导入BOM
Groovy
build.gradle
dependencies {
implementation platform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE') // (1)
implementation 'com.google.code.gson:gson' // (2)
implementation 'dom4j:dom4j'
}
Kotlin
build.gradle.kts
dependencies {
implementation(platform("org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE")) // (1)
implementation("com.google.code.gson:gson") // (2)
implementation("dom4j:dom4j")
}
-
应用Spring Boot Dependencies BOM
-
添加依赖项,其版本由该BOM表定义
您可以了解更多关于此功能之间的差异platform()
,并enforcedPlatform()
在上一节importing version recommendations from a Maven BOM。
✨您可以使用此功能将
<dependencyManagement>
来自任何依赖项的POM 的信息应用于Gradle构建,即使那些没有打包类型为的信息也是如此pom
。双方platform()
并enforcedPlatform()
会忽略声明的依赖<dependencies>
块。
迁移多模块构建(项目聚合)
Maven的多模块构建与Gradle的多项目构建很好地映射。尝试相应的教程,以了解如何设置基本的多项目Gradle构建。
要迁移多模块Maven构建,只需执行以下步骤:
1.创建一个与根POM块匹配的<modules>
设置脚本。
例如,以下代码<modules>
块:
<modules>
<module>simple-weather</module>
<module>simple-webapp</module>
</modules>
可以通过在设置脚本中添加以下行来迁移:
例子5.声明哪些项目是构建的一部分
Groovy
build.gradle
rootProject.name = 'simple-multi-module' // (1)
include 'simple-weather', 'simple-webapp' // (2)
Kotlin
build.gradle.kts
rootProject.name = "simple-multi-module" // (1)
include("simple-weather", "simple-webapp") // (2)
-
设置整个项目的名称
-
配置两个子项目作为此构建的一部分
Output of gradle projects
> gradle projects
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'simple-multi-module'
+--- Project ':simple-weather'
\--- Project ':simple-webapp'
To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :simple-weather:tasks
2.将跨模块依赖项替换为项目依赖项。
3.使用跨项目配置复制项目继承。
这基本上涉及创建一个根项目构建脚本,该脚本将共享配置注入到适当的子项目中。
跨项目共享版本
如果要复制在根POM文件的dependencyManagement
部分中声明的具有依赖项版本的Maven模式,最好的方法是利用java-platform
插件。您将需要为此添加一个专用项目,并在构建的常规项目中使用它。有关此模式的更多详细信息,请参见文档。
迁移Maven配置文件和属性
Maven允许您使用各种属性对构建进行参数化。一些是项目模型的只读属性,其他是在POM中用户定义的。它甚至允许您将系统属性视为项目属性。
Gradle具有类似的项目属性系统,尽管它可以区分项目属性和系统属性。例如,您可以在以下位置定义属性:
-
the build script
-
a
gradle.properties
file in the root project directory -
a
gradle.properties
file in the$HOME/.gradle
directory
这些不是唯一的选择,因此,如果您有兴趣了解有关如何以及在何处定义属性的更多信息,请查阅“构建环境”一章。
您需要了解的一项重要行为是,在构建脚本和一个外部属性文件中定义了相同的属性时会发生什么:构建脚本值优先。总是。幸运的是,您可以模仿配置文件的概念以提供可覆盖的默认值。
这使我们进入了Maven配置文件。这些是根据环境,目标平台或任何其他类似因素启用和禁用不同配置的方法。从逻辑上讲,它们仅是有限的“ if”语句。并且由于Gradle具有更强大的声明条件的方法,因此它不需要对配置文件的正式支持(依赖项的POM中除外)。您将看到,通过将条件与辅助构建脚本结合起来,可以轻松获得相同的行为。
假设您有不同的部署设置,具体取决于环境:本地开发(默认),测试环境和生产。要添加型材式的行为,首先在项目的根每个环境中创建构建脚本:profile-default.gradle
,profile-test.gradle
,和profile-prod.gradle
。然后,您可以根据自己选择的项目属性有条件地应用这些概要文件脚本之一。
下面的示例演示了使用名为的项目属性buildProfile
和配置文件脚本的基本技术,该脚本简单地初始化了名为的额外项目属性message
:
例子6.模仿Gradle中的Maven配置文件的行为
Groovy
build.gradle
if (!hasProperty('buildProfile')) ext.buildProfile = 'default' // (1)
apply from: "profile-${buildProfile}.gradle" // (2)
task greeting {
doLast {
println message // (3)
}
}
profile-default.gradle
ext.message = 'foobar' // (4)
profile-test.gradle
ext.message = 'testing 1 2 3' // (4)
profile-prod.gradle
ext.message = 'Hello, world!' // (4)
Kotlin
build.gradle.kts
val buildProfile: String? by project // (1)
apply(from = "profile-${buildProfile ?: "default"}.gradle.kts") // (2)
tasks.register("greeting") {
val message: String by project.extra
doLast {
println(message) // (3)
}
}
profile-default.gradle.kts
val message by extra("foobar") // (4)
profile-test.gradle.kts
val message by extra("testing 1 2 3") // (4)
profile-prod.gradle.kts
val message by extra("Hello, world!") // (4)
-
检查(Groovy)是否存在或绑定(Kotlin)
buildProfile
项目属性 -
使用
buildProfile
脚本文件名中的值应用适当的配置文件脚本 -
打印出
message
额外项目属性的值 -
初始化
message
额外的项目属性,然后可以在主构建脚本中使用其值
Output of gradle greeting
> gradle greeting
foobar
Output of gradle -PbuildProfile=test greeting
> gradle -PbuildProfile=test greeting
testing 1 2 3
您不仅限于检查项目属性。您还可以检查环境变量,JDK版本,运行内部版本的OS或您可以想象的任何其他内容。
要记住的一件事是,高级条件语句使构建更难以理解和维护,类似于它们使面向对象的代码复杂化的方式。配置文件也是如此。Gradle提供了许多更好的方法来避免广泛使用Maven经常需要的配置文件,例如,通过配置彼此不同的多个任务。请参见Maven发布插件创建的publishPubNamePublicationToRepoNameRepository
任务。
有关在Gradle中使用Maven概要文件的冗长讨论,请参阅此博客文章。
筛选资源
Maven有一个称为的阶段,默认情况下process-resources
目标已resources:resources
绑定到该阶段。这为构建作者提供了对各种文件(例如Web资源,打包的属性文件等)执行变量替换的机会。
Gradle的Java插件提供了processResources
执行相同操作的任务。这是一个复制任务,src/main/resources
默认情况下将文件从配置的资源目录复制 到输出目录。与任何Copy
任务一样,您可以对其进行配置以执行文件过滤,重命名和内容过滤。
例如,以下配置将源文件视为Groovy SimpleTemplateEngine
模板,version
并buildNumber
为这些模板提供属性:
例子7.通过processResources
任务过滤资源的内容
Groovy
build.gradle
processResources {
expand(version: version, buildNumber: currentBuildNumber)
}
Kotlin
build.gradle.kts
tasks {
processResources {
expand("version" to version, "buildNumber" to currentBuildNumber)
}
}
请参阅CopySpec的API文档以查看所有可用选项。
配置集成测试
许多Maven的建立某种形式的一体化集成测试,它的Maven通过一组额外的阶段的支持:pre-integration-test
,integration-test
,post-integration-test
,和verify
。它还使用Failsafe插件代替Surefire,以便失败的集成测试不会自动使构建失败(因为您可能需要清理资源,例如正在运行的应用程序服务器)。
如我们在Testing in Java & JVM projects章节中所述,此行为很容易在带有源集的Gradle中复制。然后,您可以使用Task.finalizedBy()将清理任务(例如关闭测试服务器的清理任务)配置为始终在集成测试之后运行,而不管它们是否成功。
如果您确实不希望集成测试使构建失败,那么可以使用Java测试一章的“测试执行“部分中描述的Test.ignoreFailures设置。
源集还为您在集成测试中放置源文件的位置提供了很大的灵活性。您可以轻松地将它们保存在与单元测试相同的目录中,或更可取的是,保存在单独的源目录中,例如src/integTest/java
。要支持其他类型的测试,您只需添加更多源集和测试任务!
迁移常用插件
Maven和Gradle共享一种通过插件扩展构建的通用方法。尽管表面上的插件系统有很大不同,但是它们共享许多基于功能的插件,例如:
-
Shade/Shadow
-
Jetty
-
Checkstyle
-
JaCoCo
-
AntRun (请参阅下一节)
为什么这么重要?因为许多插件依赖于标准Java约定,所以迁移仅是在Gradle中复制Maven插件的配置即可。例如,这是一个简单的Maven Checkstyle插件配置:
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<linkXRef>false</linkXRef>
</configuration>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
...
迁移到Gradle时,可以安全地忽略配置块之外的所有内容。在这种情况下,相应的Gradle配置如下所示:
例子8.配置Gradle Checkstyle插件
Groovy
build.gradle
checkstyle {
config = resources.text.fromFile('checkstyle.xml', 'UTF-8')
showViolations = true
ignoreFailures = false
}
Kotlin
build.gradle.kts
checkstyle {
config = resources.text.fromFile("checkstyle.xml", "UTF-8")
isShowViolations = true
isIgnoreFailures = false
}
Checkstyle任务会自动添加为check
任务的依赖项,其中还包括test
。如果要确保Checkstyle在测试之前运行,则只需使用mustRunAfter()方法指定一个顺序即可:
例子9.控制checkstyle
任务何时运行
Groovy
build.gradle
test.mustRunAfter checkstyleMain, checkstyleTest
Kotlin
build.gradle.kts
tasks {
test {
mustRunAfter(checkstyleMain, checkstyleTest)
}
}
如您所见,Gradle配置通常比Maven等效配置短得多。您还将拥有一个更加灵活的执行模型,因为您不再受Maven固定阶段的约束。
从Maven迁移项目时,请不要忘记源集。与Maven相比,它们通常为处理集成测试或生成的源提供了更优雅的解决方案,因此您应将它们纳入迁移计划中。
Ant目标
许多Maven构建依赖于AntRun插件来自定义构建,而没有实现自定义Maven插件的开销。Gradle没有等效的插件,因为Ant通过该ant
对象是Gradle构建中的一等公民。例如,您可以使用Ant的Echo任务,如下所示:
例子10.调用Ant任务
Groovy
build.gradle
task sayHello {
doLast {
ant.echo message: 'Hello!'
}
}
Kotlin
build.gradle.kts
tasks.register("sayHello") {
doLast {
ant.withGroovyBuilder {
"echo"("message" to "Hello!")
}
}
}
本机还支持Ant属性和文件集。要了解更多信息,请参阅《从Gradle中使用Ant》。
💡仅创建自定义任务类型来替换Ant为您所做的工作可能更简单,更简洁。然后,您可以更轻松地从增量构建和其他有用的Gradle功能中受益。
了解您不需要哪些插件
值得记住的是,Gradle版本通常比Maven版本更易于扩展和自定义。在这种情况下,这意味着您可能不需要Gradle插件来替换Maven。例如,Maven Enforcer插件允许您控制依赖项版本和环境因素,但是可以在常规Gradle构建脚本中轻松配置这些内容。
处理不常见和自定义的插件
您可能会遇到在Gradle中没有对应版本的Maven插件,尤其是当您或组织中的某人编写了自定义插件时。这种情况取决于您了解Gradle(以及可能的Maven)的工作方式,因为您通常必须编写自己的插件。
为了进行迁移,Maven插件有两种主要类型:
-
Those that use the Maven project object.
-
Those that don’t.
为什么这很重要?因为如果使用后者之一,则可以轻松地将其重新实现为自定义Gradle任务类型。只需定义与mojo参数相对应的任务输入和输出,然后将执行逻辑转换为任务动作即可。
如果插件依赖于Maven项目,那么您将不得不重写它。不要首先考虑Maven插件的工作原理,而要看看它试图解决的问题。然后尝试解决如何在Gradle中解决该问题。您可能会发现这两个构建模型之间的差异足以使Maven插件代码“转录”到Gradle插件中才有效。从好的方面来说,该插件可能比原始的Maven插件更容易编写,因为Gradle具有更丰富的构建模型和API。
如果您确实需要通过构建脚本或插件来实现自定义逻辑,请查看与插件开发相关的指南。另外,请务必熟悉Gradle的 Groovy DSL Reference,该参考提供了有关您将使用的API的全面文档。它详细介绍了标准配置块(以及支持他们的对象),系统(核心类型Project
,Task
等等),和一组标准的任务类型。主要入口点是Project接口,因为它是支持构建脚本的顶级对象。
进一步阅读
本章涵盖了将Maven构建迁移到Gradle的主要主题。剩下的就是迁移期间或迁移之后可能有用的其他一些方面:
-
了解如何配置Gradle的构建环境,包括用于运行Gradle的JVM设置
-
了解如何有效构建构建
-
配置Gradle的日志并在构建中使用
最后,本指南仅涉及Gradle的一些功能,我们鼓励您从用户手册的其他章节以及教程式的Gradle Guides中了解其余内容。