尽管我们只能使用一个模块来创建一个工作的应用程序,但是有时将我们的应用程序划分为多个较小的模块是比较明智的。
因为这是一个相当普遍的用例,所以每个自重的构建工具都必须支持它,Gradle也不例外。 如果Gradle项目具有多个模块,则称为多项目构建。
这篇博客文章描述了如何使用Gradle创建多项目构建。
让我们开始看一下Gradle构建的需求。
补充阅读:
如果您不熟悉Gradle, 则应先阅读以下博客文章,然后再继续阅读此博客文章:
- Gradle入门:简介可帮助您安装Gradle,描述Gradle构建的基本概念,并描述如何使用Gradle插件向构建中添加功能。
- Gradle入门:我们的第一个Java项目描述了如何使用Gradle创建Java项目并将应用程序打包到可执行jar文件中。
- Gradle入门:依赖性管理介绍了如何管理Gradle项目的依赖性。
我们的Gradle构建要求
我们的示例应用程序具有两个模块:
- 核心模块包含我们应用程序的其他模块所使用的通用组件。 在我们的例子中,它仅包含一个类: MessageService类返回字符串“ Hello World!”。 该模块只有一个依赖性:它具有一个使用Junit 4.11的单元测试。
- app模块包含HelloWorld类,该类启动我们的应用程序,从MessageService对象获取消息,并将接收到的消息写入日志文件。 该模块具有两个依赖性:它需要核心模块,并使用Log4j 1.2.17作为日志记录库。
我们的Gradle版本还具有其他两个要求:
- 我们必须能够使用Gradle运行我们的应用程序。
- 我们必须能够创建不使用所谓的“胖罐”方法的可运行二进制分发。
如果您不知道如何使用Gradle运行应用程序并创建可运行的二进制发行版,
您应先阅读以下博客文章,然后再继续阅读此博客文章:
- Gradle入门:创建二进制分发
让我们继续前进,了解如何创建满足我们要求的多项目构建。
创建多项目构建
我们的下一步是创建一个包含两个子项目的多项目Gradle构建: app和core 。 让我们从创建Gradle构建的目录结构开始。
创建目录结构
因为核心和应用程序模块使用Java,所以它们都使用Java项目的默认项目布局 。 我们可以按照以下步骤创建正确的目录结构:
- 创建核心模块( core )的根目录,并创建以下子目录:
- src / main / java目录包含核心模块的源代码。
- src / test / java目录包含核心模块的单元测试。
- 创建应用程序模块( app )的根目录,并创建以下子目录:
- src / main / java目录包含应用程序模块的源代码。
- src / main / resources目录包含应用程序模块的资源。
现在,我们已经创建了所需的目录。 下一步是配置Gradle构建。 让我们从配置多项目构建中包含的项目开始。
配置我们的多项目构建中包含的项目
通过执行以下步骤,我们可以配置包含在多项目构建中的项目:
- 将settings.gradle文件创建到根项目的根目录。 多项目Gradle构建必须具有此文件,因为它指定了多项目构建中包含的项目。
- 确保应用程序和核心项目包含在我们的多项目版本中。
我们的settings.gradle文件如下所示:
include 'app'
include 'core'
补充阅读:
- Gradle用户指南:56.2设置文件
- Gradle DSL参考:设置
让我们继续并配置核心项目。
配置核心项目
我们可以按照以下步骤配置核心项目:
- 将build.gradle文件创建到核心项目的根目录。
- 通过应用Java插件来创建Java项目。
- 确保核心项目从中央Maven2存储库获取其依赖项。
- 声明JUnit依赖关系(版本4.11)并使用testCompile配置。 此配置描述了核心项目在可以对其单元测试进行编译之前需要JUnit库。
核心项目的build.gradle文件如下所示:
apply plugin: 'java'repositories {mavenCentral()
}dependencies {testCompile 'junit:junit:4.11'
}
补充阅读:
- Gradle入门:我们的第一个Java项目
- Gradle入门:依赖管理
让我们继续并配置应用程序项目。
配置应用程序项目
在配置应用程序项目之前,我们必须快速浏览属于同一多项目构建的此类依赖项的依赖项管理。 这些依赖关系称为项目依赖关系。
如果我们的多项目构建具有项目A和B,并且项目B的编译需要项目A,则可以通过向项目B的build.gradle文件中添加以下依赖项声明来配置此依赖项:
dependencies {compile project(':A')
}
补充阅读:
- Gradle用户指南:51.4.3。 项目依赖
- Gradle用户指南:57.7。 项目库依赖项
现在,我们可以按照以下步骤配置应用程序项目:
- 将build.gradle文件创建到应用程序项目的根目录。
- 通过应用Java插件来创建Java项目。
- 确保应用程序项目从中央Maven2存储库获取其依赖项。
- 配置所需的依赖项。 该应用程序项目在编译时具有两个依赖关系:
- Log4j(版本1.2.17)
- 核心模块
- 创建一个可运行的二进制发行版 。
该应用程序项目的build.gradle文件如下所示:
apply plugin: 'application'
apply plugin: 'java'repositories {mavenCentral()
}dependencies {compile 'log4j:log4j:1.2.17'compile project(':core')
}mainClassName = 'net.petrikainulainen.gradle.client.HelloWorld'task copyLicense {outputs.file new File("$buildDir/LICENSE")doLast {copy {from "LICENSE"into "$buildDir"}}
}applicationDistribution.from(copyLicense) {into ""
}
补充阅读:
- Gradle入门:创建二进制分发
让我们继续并删除从核心和应用程序项目的构建脚本中找到的重复配置。
删除重复的配置
当我们配置多项目构建的子项目时,我们向核心和应用项目的构建脚本添加了重复的配置:
- 因为两个项目都是Java项目,所以它们都应用Java插件。
- 这两个项目都使用中央Maven 2存储库。
换句话说,两个构建脚本都包含以下配置:
apply plugin: 'java'repositories {mavenCentral()
}
让我们将此配置移到我们的根项目的build.gradle文件中。 在执行此操作之前,我们必须学习如何在根项目的build.gradle文件中配置子项目。
如果要将配置添加到名为core的单个子项目中,则必须将以下代码段添加到根项目的build.gradle文件中:
project(':core') {//Add core specific configuration here
}
换句话说,如果要将重复的配置移到根项目的构建脚本中,则必须将以下配置添加到其build.gradle文件中:
project(':app') {apply plugin: 'java'repositories {mavenCentral()}
}project(':core') {apply plugin: 'java'repositories {mavenCentral()}
}
这并不能真正改变我们的处境。 我们的构建脚本中仍然有重复的配置。 唯一的区别是,现在可以从根项目的build.gradle文件中找到重复的配置。 让我们消除这种重复的配置。
如果要向根项目的子项目添加通用配置,则必须将以下代码段添加到根项目的build.gradle文件中:
subprojects {//Add common configuration here
}
从根项目的build.gradle文件中删除重复的配置后,其外观如下:
subprojects {apply plugin: 'java'repositories {mavenCentral()}
}
如果我们拥有多项目构建中所有项目共享的配置,则应将以下代码段添加到
我们的根项目的build.gradle文件:allprojects {//Add configuration here }
补充阅读:
- Gradle用户指南:57.1跨项目配置
- Gradle用户指南:57.2子项目配置
现在,我们可以从子项目的构建脚本中删除重复的配置。 我们的子项目的新构建脚本如下所示:
core / build.gradle文件如下所示:
dependencies {testCompile 'junit:junit:4.11'
}
app / build.gradle文件如下所示:
apply plugin: 'application'dependencies {compile 'log4j:log4j:1.2.17'compile project(':core')
}mainClassName = 'net.petrikainulainen.gradle.client.HelloWorld'task copyLicense {outputs.file new File("$buildDir/LICENSE")doLast {copy {from "LICENSE"into "$buildDir"}}
}applicationDistribution.from(copyLicense) {into ""
}
现在,我们已经创建了一个多项目Gradle构建。 让我们找出我们刚刚做了什么。
我们只是做什么?
当我们在多项目构建的根目录中运行命令gradle projects时,我们将看到以下输出:
> gradle projects
:projects------------------------------------------------------------
Root project
------------------------------------------------------------Root project 'multi-project-build'
+--- Project ':app'
\--- Project ':core'To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :app:tasksBUILD SUCCESSFUL
如我们所见,该命令列出了根项目的子项目( app和core )。 这意味着我们刚刚创建了一个具有两个子项目的多项目Gradle构建。
当我们在多项目构建的根目录中运行命令gradle任务时,我们看到以下输出(下面仅显示了相关部分):
> gradle tasks
:tasks------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------Application tasks
-----------------
distTar - Bundles the project as a JVM application with libs and OS specific scripts.
distZip - Bundles the project as a JVM application with libs and OS specific scripts.
installApp -Installs the project as a JVM application along with libs and OS specific scripts
run - Runs this project as a JVM application
如我们所见,我们可以使用Gradle运行我们的应用程序,并创建一个不使用所谓的“胖子”方法的二进制发行版。 这意味着我们已经满足了Gradle构建的所有要求。
附加信息:
- Gradle用户指南:11.6。 获取有关构建的信息
让我们继续前进,找出从这篇博客文章中学到的知识。
摘要
这篇博客文章教会了我们三件事:
- 多项目构建必须在根项目的根目录中具有settings.gradle文件,因为它指定了多项目构建中包含的项目。
- 如果必须在多项目构建的所有项目中添加通用配置或行为,则应将此配置(使用allprojects )添加到根项目的build.gradle文件中。
- 如果必须在根项目的子项目中添加通用配置或行为,则应将此配置(使用subprojects )添加到根项目的build.gradle文件中。
PS:您可以从Github获得此博客文章的示例应用程序 。
翻译自: https://www.javacodegeeks.com/2015/01/getting-started-with-gradle-creating-a-multi-project-build.html