Gradle for Java — Multi Module Projects

Tinghuan Wang
summer's code life
Published in
8 min readJul 15, 2021

第一篇文章「Gradle for JAVA — init」只是用gradle 建立java application,還沒建立java web application,接著了解Groovy語法「Gradle for JAVA — Groovy」,第三篇文章使用Gradle建立 Web Application「Gradle for Java — Create Java Web Application」,今天要來使用Gradle 建立Multi Module Projects。

使用Java建立Application 通常會分很多layer,像是會分成data、integration、services。

web 用來放置JSP、Servelet…。services用來放商業邏輯。integration用來放呼叫第三方api。data 用來放從db 取回來的資料。每個layer彼此間會互相使用

每個layer都是一個Java gradle Project,因此要學習multi module要怎麼設定,在root folder,會有兩個個檔案一個是settings.gradle用來configure 這些subProject,另外一個檔案是build.gradle。

建立multi layer

第一步先建立一個folder:couponapp

建立web:

$ gradle init
$ 2:application
$ 3:Java
$ 1:no
$ 1:Groovy
$ 1:JUnit
$ Project name (default: couponapp)
$ Source package:com.summer.gradle

如果gradle是6.6.7 版本以後gradle.build會放在app 資料夾底下。

打開settings.gradle 檔案也可以看到會包含app的subproject

rootProject.name = 'couponapp'
include('app')

將app 資料夾複製2份,並將名字改成data、integration、services。在建立一個空的資料夾web。

web 資料夾放置「Gradle for Java — Create Java Web Application」這篇文章所建立的Java Web Application底下的app。

settings.gradle 修改成

rootProject.name = 'couponapp'
include('web')
include('services')
include('integration')
include('data')

執行couponapp task

直接在root folder 執行

$ gradle build

執行完之後可以看到那四個資料夾底下都多了build資料夾。

在root folder執行所有的sub task

$ gradle tasks --all

會看到所有sub module 的 task。下圖列出一些task 內容。

當進入sub folder 執行 gradle tasks — all 就只會列出此sub module 的task。

除了sub module 可以有自己的build.gradle 檔案,在root 也可以有自己的 build.gradle,在root 建立build.gradle檔案後輸入:

task printProjectName{
doLast(){
println project.name
}
}

在root folder 就可以直接執行此task。

$ gradle printProjectName

可是如果進入sub module 就無法執行此task,如果想要每個sub module 都執行。需要改成:

allprojects({
task printProjectName{
doLast(){
println project.name
}
}
})

如果想要將某個task 給sub module 但是不給root ,可以使用

subprojects({
task printProjectName{
doLast(){
println project.name
}
}
})

如果想要在root folder 直接指定某個sub module

$ gradle :<sub folder name>:<task name>// 範例
$ gradle :web:clean

Reuse Build logic

在建立couponapp folder的時候我們就以就知到data、integration、services這三個資料夾內容長得一模一樣,build.gradle 檔案內容也都一樣,可以將build.gradle改成如下:

plugins {
id 'application'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'junit:junit:4.13'
}

所以目前會有三個sub module的build.gradle長得一樣,而要如何reuse,可以將root folder底下的build.gradle改成:

subprojects({
apply plugin: 'application'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'junit:junit:4.13'
}
})

然後清空data、integration、services的build.gradle檔案。

Gradle for Java — Create Java Web Application」這篇文章有學到gradle.build可以加properties,因此在root gradle.build檔案加上version和group。

subprojects({
apply plugin: 'application'
version='1.1.0'
group='com.summer.couponapp'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'junit:junit:4.13'
}
})

執行以下語法後,可以看到build 出來的jar 檔案都有加上version

$ gradle clean build

Add dependency From root folder

如果想要從root build.gradle 指定sub module 加上dependency。

project(':web'){
dependencies{
implementation project(':services')
}
}

代表web project 把services project 當作一個jar 檔案。也就是說在build web project之前要先build services project。

秀出dependies

$ gradle :<sub folder>:dependencies// 範例
$ gradle :web:dependencies

--

--