Gradle Tips
在過去一年左右,我開始使用Gradle作為我構(gòu)建基于JVM項目的主要工具。 在使用Gradle之前,我是一個Apache Maven用戶爷耀。 Gradle分別從Apache Maven和Apache Ant中汲取了優(yōu)點(diǎn)。 Gradle從Ant中獲取了靈活的特性拍皮,從Maven得到了配置歹叮,依賴關(guān)系管理和插件的基本規(guī)范。 Gradle和Ant一樣铆帽,將任務(wù)作為一等公民對待咆耿。
Gradle構(gòu)建有三個不同的階段 - 初始化,配置和執(zhí)行爹橱。 初始化階段用來確定所有將參與構(gòu)建過程的項目票灰,并為每個項目創(chuàng)建一個Project實(shí)例。 在配置階段宅荤,它會執(zhí)行所有參與構(gòu)建過程的項目的構(gòu)建腳本屑迂。 最后,在執(zhí)行階段冯键,所有在配置階段配置好的任務(wù)都會被執(zhí)行惹盼。
在本文中,我將列出我在過去一年左右學(xué)到的小技巧惫确。
Contributing to Gradle tips
如果你看到錯誤或者可以做得更好的地方也請貢獻(xiàn)你的一份力量手报!提個issue或是提交pull request給我都是可以的蚯舱。歡迎各種貢獻(xiàn),包括更正掩蛤,添加枉昏,改進(jìn)和翻譯。
Tip 1: 使用Gradle Wrapper
當(dāng)我開始使用Gradle揍鸟,其中一個功能——對包裝腳本的支持使我印象深刻兄裂。 Gradle的wrapper將自己包含在項目中,獨(dú)立于構(gòu)建工具的安裝阳藻。 它允許您以零配置方式用Gradle構(gòu)建項目(無需先安裝Gradle distribution)晰奖。 這將確保每個人都使用相同版本的構(gòu)建工具。
要為項目創(chuàng)建Gradle wrapper腳本腥泥,可以運(yùn)行以下命令:
$ gradle wrapper --gradle-version 2.14.1
你需要安裝Gradle到你的電腦上以運(yùn)行以上的命令(譯者注:可能還要加環(huán)境變量)匾南。如果你用的是Mac,你可以用brew安裝gradle蛔外。
這將在你的工程里生成少許文件gradlew
蛆楞、gradlew.bat
、 gradle/wrapper/gradle-wrapper.jar
和gradle/wrapper/gradle-wrapper.properties
夹厌。
確保沒有在版本控制工具中忽略
gradle-wrapper.jar
文件臊岸。默認(rèn)情況下版本控制會忽略.jar文件
在任何時候,如果你想升級Gradle版本只是重新生成Gradle wrapper腳本傳遞它要使用的Gradle版本尊流。 假設(shè)我們要升級到Gradle 3.0-milestone-2帅戒,再次運(yùn)行如下命令:
$ gradle wrapper --gradle-version 3.0-milestone-2
還有,為./gradlew
設(shè)置一個別名也是個好主意
alias gradle="./gradlew"
Tip 2: 查看依賴圖表
要查看項目的依賴關(guān)系圖崖技,您可以運(yùn)行以下命令:
$ gradle dependencies
Tip 3: 構(gòu)建單獨(dú)的工程
Gradle同時支持單一項目構(gòu)建和多項目構(gòu)建逻住。我們假設(shè)我們的多項目結(jié)構(gòu)如下所示:
app
api
model
rest
core
web
itests
只構(gòu)建rest
工程我們可以運(yùn)行以下命令
$ gradle api:rest:build
Tip 4: 排除某些任務(wù)
你可以用-x
選項去排除一個任務(wù)。假設(shè)我們希望跳過測試我們可以用以下的命令:
$ gradle clean build -x test
Tip 5: 分析你的構(gòu)建
Gradle內(nèi)置了對分析的支持迎献。 如果您遇到性能問題瞎访,應(yīng)該使用--profile
選項來生成配置文件報告。 報告 會顯示不同任務(wù)花費(fèi)的時間吁恍。 假設(shè)我們想要分析構(gòu)建任務(wù)扒秸,然后我們可以運(yùn)行以下命令:
$ gradle --profile build
這將在目錄build/reports/profile
下生成報告。
![gradle-profile](https://github.com/shekhargulati/gradle-tips/raw/master/images/gradle-profile.png)
Tip 6: Perform dry run
有時你想要查看所有在編譯中將被執(zhí)行的所有任務(wù)擔(dān)憂不想執(zhí)行它們冀瓦。這個場景下Gradle提供``--dry-run```命令:
$ gradle build --dry-run
Tip 7: 安置項目jar包到本地Maven倉庫
$ gradle install
Tip 8:查看Gradle任務(wù)
$ gradle tasks
這個命令并不會列出所有任務(wù)伴奥。要用--all
來運(yùn)行:
$ gradle tasks --all
Tip 9: 使用Gradle守護(hù)程序(Daemon)
加快Gradle構(gòu)建的最簡單辦法就是用Gradle守護(hù)進(jìn)程進(jìn)行構(gòu)建。Gradle守護(hù)進(jìn)程是一個長時間存活的后臺進(jìn)程翼闽,在其生命周期內(nèi)只執(zhí)行一次引導(dǎo)拾徙。 默認(rèn)情況下未啟用Gradle守護(hù)程序。 要使用Gradle守護(hù)進(jìn)程感局,您可以在構(gòu)建命令中使用--daemon
標(biāo)志尼啡。
$ gradle build --daemon
它將在3.0版本默認(rèn)開啟
每次傳遞--daemon
標(biāo)志都很麻煩暂衡,因此您可以通過在開發(fā)機(jī)器上的~/.gradle/gradle.properties
文件中添加此標(biāo)志來啟用它。
org.gradle.daemon=true
Tip 10: 多線程構(gòu)建
打開~/.gradle/gradle.properties
并添加以下行崖瞭。
org.gradle.parallel=true
Tip 11: 自定義Gradle任務(wù)
您可以通過覆蓋其doFirst和doLast生命周期方法來自定義任何Gradle任務(wù)狂巢。 讓我們假設(shè)我們想在執(zhí)行測試之前和之后添加打印語句,我們可以通過以下操作:
apply plugin:'java'
test.doFirst {
println("running tests...")
}
test.doLast {
println("done executing tests...")
}
Tip 12: 為Gradle守護(hù)進(jìn)程提供JVM參數(shù)
您可以通過在~/.gradle/gradle.properties
中輸入一行來為Gradle守護(hù)程序指定JVM參數(shù)书聚,如下所示:
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
Tip 13: 用離線模式運(yùn)行
$ gradle build --offline
Tip 14: 按需配置
按需配置是Gradle的孵化功能唧领,因此默認(rèn)情況下不啟用。
$ gradle clean build --configure-on-demand
如果您希望將其設(shè)置為默認(rèn)選項寺惫,則可以通過向~/.gradle/gradle.properties
中添加以下代碼為全局提供此選項
org.gradle.configureondemand=true
Tip 15: 刷新Gradle依賴緩存
$ gradle clean build --refresh-dependencies
你也可以手動刪除 ~/.gradle/caches.
疹吃。下一次你構(gòu)建的時候它會下載所有依賴并加入到緩存中蹦疑。
假設(shè)你在Gradle中用于放置jar文件的目錄為lib
西雀。
dependencies {
compile files('libs/myjar.jar')
}
也能像下面這樣做:
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
compile name: 'myjar'
}
Tip 17: 將本地目錄中的所有jar加入依賴
如果你需要把一個目錄下的所有l(wèi)ibs加入依賴,那你就可以像下面這樣做:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
Tip 18: 構(gòu)建項目和所有它所依賴的項目
$ gradle api:model:buildNeeded
Tip 19: 構(gòu)建項目和所有依賴它的
$ gradle api:rest:buildDependents
Tip 20: 為構(gòu)建腳本提供默認(rèn)任務(wù)
為項目定義默認(rèn)任務(wù)是一個很好的做法歉摧,以便初次使用者可以輕松開始您的項目艇肴。 在您的Gradle腳本中,定義defaultTasks變量來傳遞它應(yīng)該執(zhí)行的任務(wù)叁温。
defaultTasks "clean","build"
現(xiàn)在如果一個用戶運(yùn)行gradle
命令再悼,默認(rèn)任務(wù)將被執(zhí)行
Tip 21: 創(chuàng)建文件的校驗(yàn)和
apply plugin: 'java'
archivesBaseName = 'checksum-sample'
jar.doLast { task ->
ant.checksum file: task.archivePath
}
Tip 22: 給構(gòu)建文件取不同的名字
默認(rèn)的文件名為 build.gradle
。你可以在settings.gradle
用以下方法進(jìn)行重命名:
rootProject.buildFileName = "gradle-tips.gradle"
現(xiàn)在把你的build.gradle
改名成了gradle-tips.gradle
Tip 23: 在多項目Gradle工程中為構(gòu)建腳本取不同的名字
為了方便膝但,我們用build.gradle
作為Gradle構(gòu)建腳本的名稱冲九。當(dāng)你在多項目Gradle工程中,對構(gòu)建腳本使用不同的名稱是有意義的跟束。 我們假設(shè)我們的多模塊項目如下所示:
app
api
core
web
itests
默認(rèn)情況下莺奸,所有這些子項目都將build.gradle
作為他們的Gradle構(gòu)建文件。 我們可以通過在settings.gradle
中改變冀宴。
rootProject.children.each {
it.buildFileName = it.name + '.gradle'
}
現(xiàn)在你可以用build.gradle
作為根項目的構(gòu)建文件而子工程中為api.gradle
, core.gradle
, web.gradle
, 和itests.gradle
灭贷。
Tip 24: 使用Gradle可視化界面
你可以在命令行中用以下代碼啟動Gradle可視化界面:
$ gradle --gui
它將開啟下圖所示的可視化界面:
![gradle-gui](https://github.com/shekhargulati/gradle-tips/raw/master/images/gradle-gui.png)
Tip 25: 創(chuàng)建untar任務(wù)
task untar( type : Copy) {
from tarTree(‘dist.tar.gz’)
into ‘destFolder’
}
Tip 26: 版本沖突時的配置
在你的構(gòu)建腳本中,定義了一個如下的配置塊:
configurations {
compile.resolutionStrategy.failOnVersionConflict()
}
Tip 27: 在Gradle中使用作用域
你可以用gradle2.12版本以上提供的compileOnly
作用域來使用Maven
dependencies {
compileOnly 'javax.servlet:servlet-api:3.0-alpha-1'
}
Tip 28: 顯式設(shè)置Java編譯編碼
在你的 build.gradle
中添加如下代碼:
compileJava.options.encoding = 'UTF-8'
Tip 29: 禁用傳遞依賴關(guān)系解析
為整個配置關(guān)閉傳遞依賴關(guān)系:
configurations {
compile.transitive = false
}
Tip 30: 查看Gradle版本
用下列代碼查看Gradle版本:
$ gradle -v
------------------------------------------------------------
Gradle 2.14.1
------------------------------------------------------------
Build time: 2016-07-18 06:38:37 UTC
Revision: d9e2113d9fb05a5caabba61798bdb8dfdca83719
Groovy: 2.4.4
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_60 (Oracle Corporation 25.60-b23)
OS: Mac OS X 10.10.5 x86_64
你可以用GradleVersion.current()
查看當(dāng)前Gradle版本略贮。 你可以創(chuàng)建一個任務(wù)來做這個工作:
task gradleVersion {
group = "help"
description = "Prints Gradle version"
doLast {
logger.quiet("You are using [${GradleVersion.current()}]")
}
}
當(dāng)你運(yùn)行時你會看到:
$ gradle gradleVersion
:gradleVersion
You are using [Gradle 2.14.1]
BUILD SUCCESSFUL
Total time: 0.667 secs
Tip 31: 禁用一個任務(wù)
taskName.enabled = false
如果你想禁用測試任務(wù)甚疟,用下列代碼:
test.enabled = false
Tip 32: 初始化Gradle項目
要創(chuàng)建使用testng測試框架的Java Gradle項目,您可以使用以下命令:
$ gradle init --type java-library --test-framework testng
如果你想用JUnit逃延,那就別加上--test-framework
$ gradle init --type java-library
你也可以創(chuàng)建groovy和scala項目
$ gradle init --type scala-library
$ gradle init --type groovy-library
Tip 33: 簽名文件
apply plugin: 'signing'
signing {
sign configurations.archives
}
如果你只想在發(fā)布的版本中簽名而在快照版本中不簽名览妖,那你可以這樣做:
apply plugin: 'signing'
signing {
required { !version.endsWith("SNAPSHOT”) }
}
Tip 34: 并行運(yùn)行測試
test {
maxParallelForks = 2
}
Tip 35: 為測試設(shè)置內(nèi)存
test {
minHeapSize = ‘512m'
maxHeapSize = ‘1024m'
}
Tip 36: 用任務(wù)的短名
如果你有個任務(wù)buildServerDistribution
,想用它的短名揽祥,你可以用如下方法:
$ gradle bSD
你必須保證它在所有任務(wù)中是唯一的黄痪,如有另一個任務(wù)buildSafeDistribution
,你需要做以下區(qū)分
$ gradle bSeD
Tip 37: 查看Gradle任務(wù)的相關(guān)信息
$ gradle help --task <task name>
$ gradle help --task dependencies
Tip 38: 用調(diào)試模式運(yùn)行Gradle
$ gradle clean build --debug
Tip 39: 當(dāng)任務(wù)失敗后繼續(xù)執(zhí)行任務(wù)
$ gradle clean build --continue
Tip 40: 將Maven工程轉(zhuǎn)移至Gradle
到Maven項目中運(yùn)行以下命令:
$ gradle init --type pom
Tip 41: 強(qiáng)制Gradle重運(yùn)行即使它是最新的
$ gradle build --rerun-tasks
Tip 42: 在依賴中使用確切的版本號
你在聲明依賴時不要使用+號盔然,而該用確切的版本號桅打,這回讓你構(gòu)建過程更快更安全
Tip 43: 啟用連續(xù)構(gòu)建
如果你希望連續(xù)地運(yùn)行構(gòu)建是嗜,那你可以使用--continuous
標(biāo)識。它將查找文件改變挺尾,找到一處九江重新運(yùn)行命令鹅搪,用下列方法啟用連續(xù)測試:
$ gradle test --continuous
Tip 44: 運(yùn)行一個測試事務(wù)
有時我們只需要運(yùn)行一個測試事務(wù)而不是運(yùn)行所有測試。用下列命令即可:
$ gradle test --tests tips.CalculatorTest
想運(yùn)行CalculatorTest 中的某個部分可以這樣做:
$ gradle test --tests tips.CalculatorTest.shouldAddTwoNumbers
您還可以使用正則表達(dá)式來指定多個測試:
$ gradle test --tests "tips.Calculator*Test"
你也可以多次用--test
標(biāo)識
$ gradle test --tests tips.CalculatorTest --tests tips.Calculator1Test
在一個子模塊的測試中你可以這樣做:
$ gradle api:test --tests app.api.PingResourceTest
Tip 45: 生成源文件和java文檔jar包
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar, javadocJar
}
Tip 46: 在構(gòu)建腳本中訪問環(huán)境變量
你可以用很多方法在構(gòu)建腳本中訪問環(huán)境變量:
println(System.getenv("HOME"))
println("$System.env.HOME")
Tip 47: 配置測試日志
Gradle默認(rèn)只會在控制臺打印測試錯誤的日志遭铺。這會限制任務(wù)如何運(yùn)行的可見性丽柿。Gradle允許你用testLogging
參數(shù)來配置它。打印所有日志如下魂挂。更多信息看這里.
test {
testLogging {
events "passed", "skipped", "failed"
}
}
現(xiàn)在當(dāng)你運(yùn)行./gradlew clean build
時甫题,你也會看到通過測試的日志了。
$ gradle clean test
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
tips.CalculatorTest > shouldSubtractTwoNumbers PASSED
tips.CalculatorTest > shouldAddTwoNumbers PASSED
tips.CalculatorTest > shouldSubtractTwoNumbers1 PASSED
有一點(diǎn)要記住的是涂召,Gradle測試命令只有當(dāng)改變時才會執(zhí)行坠非。因此如果你在沒有改動的情況下再次執(zhí)行它將不會有任何結(jié)果產(chǎn)生。你將看到:test UP-TO-DATE
果正,這意味著沒有檢測到改動慌烧。你可以用./gradlew cleanTest test
指令強(qiáng)制Gradle每次都運(yùn)行測試帜消。
Tip 48: 在測試執(zhí)行期間顯示標(biāo)準(zhǔn)輸出和錯誤流
test {
testLogging {
events "passed", "skipped", "failed"
showStandardStreams = true
}
}
Tip 49: 存儲憑據(jù)
您不應(yīng)該在build.gradle
中硬編碼憑據(jù)产禾,而應(yīng)該依靠您的用戶home~/ .gradle / gradle.properties
來存儲憑據(jù)倡缠。 假設(shè)你想使用受憑證保護(hù)的Maven存儲庫。 指定憑據(jù)的一種方法是在build.gradle
中對它們進(jìn)行硬編碼迫皱,如下所示歉闰。
repositories {
maven {
credentials {
username "admin"
password "admin123"
}
url "http://nexus.mycompany.com/"
}
}
更好的方法是改變你自己的~/ .gradle / gradle.properties
nexusUsername = admin
nexusPassword = admin123
現(xiàn)在,在build.gradle
中引用這個
repositories {
maven {
credentials {
username "$nexusUsername"
password "$nexusPassword"
}
url "http://nexus.mycompany.com/"
}
}
Tip 50: 調(diào)試Java可執(zhí)行應(yīng)用程序
如果將應(yīng)用程序打包成可以通過Gradle運(yùn)行的可執(zhí)行jar卓起,那么可以通過--debug-jvm
選項來調(diào)試它和敬。 Spring Boot應(yīng)用程序作為可執(zhí)行jar運(yùn)行。 您可以使用gradle bootRun
來運(yùn)行應(yīng)用程序既绩。 要在端口5005上調(diào)試應(yīng)用程序概龄,您可以在調(diào)試模式下啟動應(yīng)用程序。
$ gdw <taskname> --debug-jvm
$ gradle bootRun --debug-jvm
Tip 51: 使用本地Maven倉庫
要用本地 ~/.m2
倉庫,你需要在build.gradle
中添加這些:
repositories {
mavenLocal()
}
Tip 52: 排除傳遞性的依賴
用下述方法排除傳遞性的依賴
compile('org.hibernate:hibernate:3.1') {
exclude module: 'cglib' //by artifact name
exclude group: 'org.jmock' //by group
}