Gradle是一種構建工具,它拋棄了基於XML的構建腳本,取而代之的是采用一種基於Groovy的內部領域特定語言。近期,Gradle獲得了極大的關注,這也是我決定去研究Gradle的原因。
這篇文章是Gradle教程的第一篇,我們有兩個目標:
- 1. 幫助我們學會安裝Gradle。
- 2. 介紹一些基本概念,這有助於我們進一步理解本教程的后面章節。
我們開始吧,先看一下如何安裝Gradle。
安裝Gradle
如果我們使用的操作系統是Windows或Linux,我們可以根據以下步驟安裝Gradle: 1. 從這個頁面下載二進制文件。 2. 解壓Zip文件,加入環境變量(在PATH中加入GRADLE_HOME/bin目錄)。
如果在安裝過程中遇到問題,可以進一步查看官方的安裝指南。 如果我們使用的操作系統是OS X,我們可以使用Homebrew安裝Gradle,在命令提示符中輸入以下命令:
1
|
brew
install
gradle
|
我們可以驗證一下Gradle是否工作正常,在命令提示符中執行命令gradle -v即可,如果Gradle工作正常,我們應該能看到以下輸出結果(當然,Windows和Linux用戶看到的結果會有細微差異)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
> gradle -
v
------------------------------------------------------------
Gradle 1.12
------------------------------------------------------------
Build
time
: 2014-04-29 09:24:31 UTC
Build number: none
Revision: a831fa866d46cbee94e61a09af15f9dd95987421
Groovy: 1.8.6
Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013
Ivy: 2.2.0
JVM: 1.8.0 (Oracle Corporation 25.0-b70)
OS: Mac OS X 10.9.3 x86_64
|
下面我們來快速瀏覽一下Gradle構建的基本概念。
Gradle構建簡介
在Gradle中,有兩個基本概念:項目和任務。請看以下詳解:
- 項目是指我們的構建產物(比如Jar包)或實施產物(將應用程序部署到生產環境)。一個項目包含一個或多個任務。
- 任務是指不可分的最小工作單元,執行構建工作(比如編譯項目或執行測試)。
那么,這些概念和Gradle的構建又有什么聯系呢?好,每一次Gradle的構建都包含一個或多個項目。
下面這張圖展示了上面所談到的這些概念的關系。
我們能夠使用以下配置文件對Gradle的構建進行配置:
- Gradle構建腳本(build.gradle)指定了一個項目和它的任務。
- Gradle屬性文件(gradle.properties)用來配置構建屬性。
- Gradle設置文件(gradle.settings)對於只有一個項目的構建而言是可選的,如果我們的構建中包含多於一個項目,那么它就是必須的,因為它描述了哪一個項目參與構建。每一個多項目的構建都必須在項目結構的根目錄中加入一個設置文件。
你可以在這篇文章中獲得更多關於Gradle構建腳本的信息。
我們繼續,下面我們看一下如果使用Gradle插件為構建工作加入新功能。
更簡短的Gradle插件簡介
Gradle的設計理念是,所有有用的特性都由Gradle插件提供,一個Gradle插件能夠:
- 在項目中添加新任務
- 為新加入的任務提供默認配置,這個默認配置會在項目中注入新的約定(如源文件位置)。
- 加入新的屬性,可以覆蓋插件的默認配置屬性。
- 為項目加入新的依賴。
Gradle用戶手冊提供了一系列標准Gradle插件。
在我們為項目加入Gradle插件時,我們可以根據名稱或類型來指定Gradle插件。
我們可以將下面這行代碼加入到build.gradle文件中,它通過名稱指定Gradle插件(這里的名稱是foo):
1
|
apply plugin:
'foo'
|
另一方面,我們也可以通過類型指定Gradle插件,將下面這行代碼加入到build.gradle文件中(這里的類型是com.bar.foo):
1
|
apply plugin:
'com.bar.foo'
|
你可以閱讀這篇文章,掌握應用插件的更多信息。
今天就到這里,我們來總結一下我們所學的內容。
總結
這篇教程講授了三部分內容:
- 我們學會了如何安裝Gradle
- 我們理解了Gradle構建的一些基本知識
- 我們了解了如何使用Gradle插件為我們的構建工作增加功能。
下一篇教程,我們會討論如何使用Gradle創建一個簡單的Java工程。
http://blog.jobbole.com/71999/
這篇教程的主要內容是講解如何用Gradle編譯和打包一個簡單的Java項目。
該Java項目只有一個需求:我們的構建腳本必須創建一個可執行的Jar文件,換句話說,我們必須能夠使用命令java -jar jarfile.jar 來運行我們的程序。我們來看一下如何滿足這個需求。
創建一個Java項目
我們可以使用Java插件(譯注:關於Gradle插件的定義,請查看第一篇教程)來創建一個Java項目,為了做到這點,我們需要把下面這段語句加入到build.gradle文件中:
1
|
apply plugin:
'java'
|
就是這樣,現在我們已經創建了一個Java項目。Java插件會在我們的構建中添加一些新的約定(如默認的項目結構),新的任務,和新的屬性。 讓我們來快速地看一下默認的項目結構。
Java項目結構
默認的項目結構如下:
- src/main/java目錄包含了項目的源代碼。
- src/main/resources目錄包含了項目的資源(如屬性文件)。
- src/test/java目錄包含了測試類。
- src/test/resources目錄包含了測試資源。所有我們構建生成的文件都會在build目錄下被創建,這個目錄涵蓋了以下的子目錄,這些子目錄我們會在這篇教程中提到,另外還有一些子目錄我們會放在以后講解。
- classes目錄包含編譯過的.class文件。
- libs目錄包含構建生成的jar或war文件。
為構建加入一個主類(main class)
讓我們創建一個簡單的主類,在這個類中會打印一個“Hello world”然后System.out出來。這個HelloWorld類的源代碼如下:
1
2
3
4
5
6
7
8
|
package
net.petrikainulainen.gradle;
public
class
HelloWorld {
public
static
void
main(String[] args) {
System.out.println(
"Hello World!"
);
}
}
|
HelloWorld類存放在src/main/java/net/petrikainulainen/gradle目錄
這很好,然而,我們還需要編譯和打包我們的項目,不是嗎?我們先看一下這個Java工程中的任務。
Java工程中的任務
Java插件在我們的構建中加入了很多任務,我們這篇教程涉及到的任務如下:
- assemble任務會編譯程序中的源代碼,並打包生成Jar文件,這個任務不執行單元測試。
- build任務會執行一個完整的項目構建。
- clean任務會刪除構建目錄。
- compileJava任務會編譯程序中的源代碼。
我們還可以執行以下命令得到一個可運行任務及其描述的完整列表
1
|
gradle tasks
|
這是一個很好的方式,不需要閱讀構建腳本,就能對你的項目進行大致的瀏覽,如果我們在項目根目錄下運行這個命令,我們可以看到以下輸出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
> gradle tasks
:tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles classes
'main'
.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles classes
'test'
.
Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]
Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation
for
the main
source
code.
Help tasks
----------
dependencies - Displays all dependencies declared
in
root project
'first-java-project'
.
dependencyInsight - Displays the insight into a specific dependency
in
root project
'first-java-project'
.
help - Displays a help message
projects - Displays the sub-projects of root project
'first-java-project'
.
properties - Displays the properties of root project
'first-java-project'
.
tasks - Displays the tasks runnable from root project
'first-java-project'
.
Verification tasks
------------------
check - Runs all checks.
test
- Runs the unit tests.
Rules
-----
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
Pattern: clean<TaskName>: Cleans the output files of a task.
To see all tasks and
more
detail, run with --all.
BUILD SUCCESSFUL
Total
time
: 2.792 secs
|
我們繼續,下面要講怎樣打包我們的項目。
打包我們的項目
我們可以通過使用兩個不同的任務來打包項目。 如果我們在命令提示符中執行命令gradle assemble,我們可以看到以下輸出:
1
2
3
4
5
6
7
8
9
10
|
> gradle assemble
:compileJava
:processResources
:classes
:jar
:assemble
BUILD SUCCESSFUL
Total
time
: 3.163 secs
|
如果我們在命令提示符中執行命令gradle build,我們可以看到以下輸出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
> gradle build
:compileJava
:processResources
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:
test
:check
:build
BUILD SUCCESSFUL
Total
time
: 3.01 secs
|
這些命令的輸出表明了它們的區別:
- assemble任務僅僅執行項目打包所必須的任務集。
- build任務執行項目打包所必須的任務集,以及執行自動化測試。這兩個命令都會在build/libs目錄中創建一個file-java-project.jar文件。默認創建的Jar文件名稱是由這個模版決定的:[projectname].jar,此外,項目的默認名稱和其所處的目錄名稱是一致的。因此如果你的項目目錄名稱是first-java-project,那么創建的Jar文件名稱就是first-java-project.jar。
現在,我們嘗試使用以下命令運行我們的程序:
1
|
java -jar first-java-project.jar
|
我們可以看到以下輸出:
1
2
|
> java -jar first-java.project.jar
No main manifest attribute,
in
first-java-project.jar
|
問題出在,我們沒有在manifest文件中配置Jar文件的主類,讓我們繼續看看怎樣解決這個問題。
配置Jar文件的主類
Java插件在我們的項目中加入了一個Jar任務,每一個Jar對象都一個manifest屬性,這個屬性是Manifest的一個實例。
我們可以對生成的Jar文件的主類進行配置,使用Manifest接口的attributes()方法。換句話說,我們可以使用一個包含鍵值對的map結構指定加入到manifest文件的屬性集。
我們能夠通過設置Main-Class屬性的值,指定我們程序的入口點。在我們對build.gradle文件進行必要的改動后,代碼如下:
1
2
3
4
5
6
7
|
apply plugin:
'java'
jar {
manifest {
attributes
'Main-Class'
:
'net.petrikainulainen.gradle.HelloWorld'
}
}
|
(JavaSE教程提供了關於manifest文件的更多信息。) 在我們執行gradle assemble或gradle build命令生成一個新的jar文件之后,我們可以執行以下命令運行jar文件:
1
|
java -jar first-java-project.jar
|
當我們運行程序時,System.out會打印出以下信息:
1
2
|
> java -jar first-java-project.jar
Hello World!
|
這就是我們今天所有的內容,我們看一下我們學到了什么。
總結
我們已經通過Gradle創建了一個簡單的Java項目,這篇教程教會了我們四點:
- 我們了解了可以使用Gradle的Java插件創建一個Java項目。
- 我們知道了Java項目的默認結構和Maven項目的默認結構是一樣的。
- 我們知道了構建所生成的所有文件都能在build目錄下找到。
- 我們知道了我們可以自定義加入到manifest文件中的屬性。
P.S. 這篇教程的示例代碼可以在Github找到。
http://blog.jobbole.com/72558/
在現實生活中,要創造一個沒有任何外部依賴的應用程序並非不可能,但也是極具挑戰的。這也是為什么依賴管理對於每個軟件項目都是至關重要的一部分。
這篇教程主要講述如何使用Gradle管理我們項目的依賴,我們會學習配置應用倉庫以及所需的依賴,我們也會理論聯系實際,實現一個簡單的演示程序。
讓我們開始吧。
倉庫管理簡介
本質上說,倉庫是一種存放依賴的容器,每一個項目都具備一個或多個倉庫。
Gradle支持以下倉庫格式:
- Ivy倉庫
- Maven倉庫
- Flat directory倉庫
我們來看一下,對於每一種倉庫類型,我們在構建中應該如何配置。
在構建中加入Ivy倉庫
我們可以通過URL地址或本地文件系統地址,將Ivy倉庫加入到我們的構建中。
如果想通過URL地址添加一個Ivy倉庫,我們可以將以下代碼片段加入到build.gradle文件中:
1
2
3
4
5
|
repositories {
ivy {
url
"http://ivy.petrikainulainen.net/repo"
}
}
|
如果想通過本地文件系統地址添加一個Ivy倉庫,我們可以將以下代碼片段加入到build.gradle文件中:
1
2
3
4
5
|
repositories {
ivy {
url
"../ivy-repo"
}
}
|
小貼士:如果你想要獲得更多關於Ivy倉庫配置的信息,你可以參考以下資源:
- Section 50.6.6 Ivy Repositories of the Gradle User Guide
- The API documentation of the IvyArtifactRepository
我們繼續,下面是如何在構建中加入Maven倉庫。
在構建中加入Maven倉庫
與Ivy倉庫很類似,我們可以通過URL地址或本地文件系統地址,將Maven倉庫加入到我們的構建中。
如果想通過URL地址添加一個Maven倉庫,我們可以將以下代碼片段加入到build.gradle文件中:
1
2
3
4
5
|
repositories {
maven {
url
"http://maven.petrikainulainen.net/repo"
}
}
|
如果想通過本地文件系統地址添加一個Maven倉庫,我們可以將以下代碼片段加入到build.gradle文件中:
1
2
3
4
5
|
repositories {
maven {
url
"../maven-repo"
}
}
|
在加入Maven倉庫時,Gradle提供了三種“別名”供我們使用,它們分別是:
- mavenCentral()別名,表示依賴是從Central Maven 2 倉庫中獲取的。
- jcenter()別名,表示依賴是從Bintary’s JCenter Maven 倉庫中獲取的。
- mavenLocal()別名,表示依賴是從本地的Maven倉庫中獲取的。
如果我們想要將Central Maven 2 倉庫加入到構建中,我們必須在build.gradle文件中加入以下代碼片段:
1
2
3
|
repositories {
mavenCentral()
}
|
小貼士:如果你想要獲取更多關於Maven倉庫配置的信息,你可以參考這篇文章:
section 50.6.4 Maven Repositories of the Gradle User Guide
我們繼續,下面是如何在構建中加入Flat Directory倉庫。
在構建中加入Flat Directory倉庫
如果我們想要使用Flat Directory倉庫,我們需要將以下代碼片段加入到build.gradle文件中:
1
2
3
4
5
|
repositories {
flatDir {
dirs
'lib'
}
}
|
這意味着系統將在lib目錄下搜索依賴,同樣的,如果你願意的話可以加入多個目錄,代碼片段如下:
1
2
3
4
5
|
repositories {
flatDir {
dirs
'libA'
,
'libB'
}
}
|
小貼士:如果你想要獲得更多關於Flat Directory倉庫配置的信息,你可以參考以下資源:
- Section 50.6.5 Flat directory repository of the Gradle User Guide
- Flat Dir Repository post to the gradle-user mailing list
我們繼續,下面要講的是,如何使用Gradle管理項目中的依賴。
依賴管理簡介
在配置完項目倉庫后,我們可以聲明其中的依賴,如果我們想要聲明一個新的依賴,可以采用如下步驟:
- 指定依賴的配置。
- 聲明所需的依賴。
讓我們看一下詳細步驟:
配置中的依賴分類
在Gradle中,依賴是按照指定名稱進行分類的,這些分類被稱為配置項,我們可以使用配置項聲明項目的外部依賴。
Java插件指定了若干依賴配置項,其描述如下:
- 當項目的源代碼被編譯時,compile配置項中的依賴是必須的。
- runtime配置項中包含的依賴在運行時是必須的。
- testCompile配置項中包含的依賴在編譯項目的測試代碼時是必須的。
- testRuntime配置項中包含的依賴在運行測試代碼時是必須的。
- archives配置項中包含項目生成的文件(如Jar文件)。
- default配置項中包含運行時必須的依賴。
我們繼續,下面是如何在項目中聲明依賴。
聲明項目依賴
最普遍的依賴稱為外部依賴,這些依賴存放在外部倉庫中。一個外部依賴可以由以下屬性指定:
- group屬性指定依賴的分組(在Maven中,就是groupId)。
- name屬性指定依賴的名稱(在Maven中,就是artifactId)。
- version屬性指定外部依賴的版本(在Maven中,就是version)。
小貼士:這些屬性在Maven倉庫中是必須的,如果你使用其他倉庫,一些屬性可能是可選的。打個比方,如果你使用Flat directory倉庫,你可能只需要指定名稱和版本。
我們假設我們需要指定以下依賴:
- 依賴的分組是foo。
- 依賴的名稱是foo。
- 依賴的版本是0.1。
- 在項目編譯時需要這些依賴。
我們可以將以下代碼片段加入到build.gradle中,進行依賴聲明:
1
2
3
|
dependencies {
compile group:
'foo'
, name:
'foo'
, version:
'0.1'
}
|
我們也可以采用一種快捷方式聲明依賴:[group]:[name]:[version]。如果我們想用這種方式,我們可以將以下代碼段加入到build.gradle中:
1
2
3
|
dependencies {
compile
'foo:foo:0.1'
}
|
我們也可以在同一個配置項中加入多個依賴,傳統的方式如下:
1
2
3
4
5
6
|
dependencies {
compile (
[group:
'foo'
, name:
'foo'
, version:
'0.1'
],
[group:
'bar'
, name:
'bar'
, version:
'0.1'
]
)
}
|
如果采用快捷方式,那可以是這樣:
1
2
3
|
dependencies {
compile
'foo:foo:0.1'
,
'bar:bar:0.1'
}
|
自然地,聲明屬於不同配置項的依賴也是可以的。比如說,如果我們想要聲明屬於compile和testCompile配置項的依賴,可以這么做:
1
2
3
4
|
dependencies {
compile group:
'foo'
, name:
'foo'
, version:
'0.1'
testCompile group:
'test'
, name:
'test'
, version:
'0.1'
}
|
同樣的,給力的快捷方式又來了( ̄︶ ̄)
1
2
3
4
|
dependencies {
compile
'foo:foo:0.1'
testCompile
'test:test:0.1'
}
|
小貼士:你可以從這篇文章中獲得更多關於依賴聲明的信息。
我們已經學習了依賴管理的基礎知識,下面我們來實現一個演示程序。
創建演示程序
演示程序的需求是這樣的:
- 演示程序的構建腳本必須使用Maven central倉庫。
- 演示程序必須使用Log4j寫入日志。
- 演示程序必須包含包含單元測試,保證正確的信息返回,單元測試必須使用JUnit編寫。
- 演示程序必須創建一個可執行的Jar文件。
我們來看一下怎樣實現這些需求。
配置倉庫
我們的演示程序的一個需求是構建腳本必須使用Maven central倉庫,在我們使用Maven central倉庫配置構建腳本后,源代碼如下:
1
2
3
4
5
6
7
8
9
10
11
|
apply plugin:
'java'
repositories {
mavenCentral()
}
jar {
manifest {
attributes
'Main-Class'
:
'net.petrikainulainen.gradle.HelloWorld'
}
}
|
我們再來看一下如何對我們的演示程序進行依賴聲明。
依賴聲明
在build.gradle文件中,我們聲明了兩個依賴:
- Log4j(版本1.2.17)用來記錄日志。
- JUnit(版本4.11)用來編寫單元測試。
在我們聲明了這些依賴后,build.gradle文件是這樣的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
apply plugin:
'java'
repositories {
mavenCentral()
}
dependencies {
compile
'log4j:log4j:1.2.17'
testCompile
'junit:junit:4.11'
}
jar {
manifest {
attributes
'Main-Class'
:
'net.petrikainulainen.gradle.HelloWorld'
}
}
|
我們繼續,稍微加入一些代碼。
編寫代碼
為了實現我們演示程序的需求,“我們不得不過度工程化一下”,我們會按照下列步驟創建程序:
- 創建一個MessageService類,當其中的getMessage()方法被調用時,返回字符串“Hello World!”。
- 創建一個MessageServiceTest類,確保MessageService類中的getMessage()方法返回字符串“Hello World!”。
- 創建程序的主類,從MessageService對象獲取信息,並使用Log4j寫入日志。
- 配置Log4j。
我們按部就班的操作一下。
首先,在src/main/java/net/petrikainulainen/gradle目錄下新建一個MessageService類並加以實現,代碼如下:
1
2
3
4
5
6
7
8
|
package
net.petrikainulainen.gradle;
public
class
MessageService {
public
String getMessage() {
return
"Hello World!"
;
}
}
|
其次,在src/main/test/net/petrikainulainen/gradle目錄下新建一個MessageServiceTest類,編寫單元測試,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package
net.petrikainulainen.gradle;
import
org.junit.Before;
import
org.junit.Test;
import
static
org.junit.Assert.assertEquals;
public
class
MessageServiceTest {
private
MessageService messageService;
@Before
public
void
setUp() {
messageService =
new
MessageService();
}
<a href=
"http://www.jobbole.com/members/test/"
rel=
"nofollow"
>
@Test
</a>
public
void
getMessage_ShouldReturnMessage() {
assertEquals(
"Hello World!"
, messageService.getMessage());
}
}
|
第三,在src/main/java/net/petrikainulainen/gradle目錄下新建一個HelloWorld類,這是程序的主類,從MessageService對象獲取信息,並使用Log4j寫入日志,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package
net.petrikainulainen.gradle;
import
org.apache.log4j.Logger;
public
class
HelloWorld {
private
static
final
Logger LOGGER = Logger.getLogger(HelloWorld.
class
);
public
static
void
main(String[] args) {
MessageService messageService =
new
MessageService();
String message = messageService.getMessage();
LOGGER.info(
"Received message: "
+ message);
}
}
|
第四,在src/main/resources目錄中,使用log4j.properties配置log4j,log4j.properties文件如下:
1
2
3
4
5
|
log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n
log4j.rootLogger=DEBUG,Stdout
|
這樣就好了,我們看看如何執行測試。
執行測試
我們可以通過以下命令執行測試。
1
|
gradle
test
|
當測試通過時,我們能看到如下輸出:
1
2
3
4
5
6
7
8
9
10
11
12
|
> gradle
test
:compileJava
:processResources
:classes
:compileTestJava
:processTestResources
:testClasses
:
test
BUILD SUCCESSFUL
Total
time
: 4.678 secs
|
然而,如果測試失敗,我們將看到如下輸出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
> gradle
test
:compileJava
:processResources
:classes
:compileTestJava
:processTestResources
:testClasses
:
test
net.petrikainulainen.gradle.MessageServiceTest > getMessage_ShouldReturnMessageFAILED
org.junit.ComparisonFailure at MessageServiceTest.java:22
1
test
completed, 1 failed
:
test
FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed
for
task
':test'
.
> There were failing tests. See the report at:
file
:
///Users/loke/Projects/Java/Blog/gradle-examples/dependency-management/build/reports/tests/index
.html
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get
more
log output.
BUILD FAILED
Total
time
: 4.461 secs
|
正如我們所看到的,如果單元測試失敗了,輸出信息中將描述以下信息:
- 哪一個測試失敗了。
- 執行了幾個測試,其中幾個失敗了。
- 測試報告的位置,測試報告提供了失敗(或成功)的測試的額外信息。
當我們執行單元測試時,Gradle會在相應目錄創建測試報告:
- build/test-results目錄包含每次測試執行的原始數據。
- build/reports/tests目錄包含一個HTML報告,描述了測試的結果。
HTML測試報告是一個非常有用的工具,因為它描述了測試失敗的原因。比如說,如果我們的單元測試認為MessageService類中的getMessage()方法返回字符串“Hello Worl1d!”,那么HTML報告看上去就像下圖一樣:
我們繼續,下面是如何打包和運行我們的演示程序。
打包和運行程序
我們能夠可以使用以下任意一種命令打包程序:gradle assembly或gradle build,這兩個命令都會在build/libs目錄中創建dependency-management.jar文件。
當我們使用java -jar dependency-management.jar命令運行演示程序時,我們可以看到如下輸出:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
> java -jar dependency-management.jar
Exception
in
thread
"main"
java.lang.NoClassDefFoundError: org
/apache/log4j/Logger
at net.petrikainulainen.gradle.HelloWorld.<clinit>(HelloWorld.java:10)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1
more
|
拋出異常的原因是,當我們運行程序時,Log4j的依賴在classpath中沒有找到。
解決這個問題最簡單的方式是創建一個所謂的“胖”Jar文件,即把所有程序運行所需的依賴都打包到Jar文件中去。
通過查閱Gradle Cookbook中的教程,可以修改構建腳本,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
apply plugin:
'java'
repositories {
mavenCentral()
}
dependencies {
compile
'log4j:log4j:1.2.17'
testCompile
'junit:junit:4.11'
}
jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
manifest {
attributes
'Main-Class'
:
'net.petrikainulainen.gradle.HelloWorld'
}
}
|
現在,我們可以運行演示程序了(打包后),一切正常:
1
2
|
> java -jar dependency-management.jar
INFO - HelloWorld - Received message: Hello World!
|
這些就是今天的內容了,我們總結一下學到了什么。
總結
這篇教程教會了我們四個方面的內容:
- 我們學會了配置構建所需的倉庫。
- 我們學會了如何聲明所需的依賴以及依賴的分類(分組)。
- 我們了解了Gradle會在測試執行后創建一個HTML測試報告。
- 我們學會了創建一個所謂的“胖”Jar文件。
如果你想要玩一玩這篇教程所涉及的演示程序,你可以從GitHub那獲取。
http://blog.jobbole.com/72992/