這篇教程的主要內(nèi)容是講解如何用Gradle編譯和打包一個簡單的Java項目读虏。
該Java項目只有一個需求:我們的構(gòu)建腳本必須創(chuàng)建一個可執(zhí)行的Jar文件,換句話說墨缘,我們必須能夠使用命令java -jar jarfile.jar 來運行我們的程序星虹。我們來看一下如何滿足這個需求零抬。
創(chuàng)建一個Java項目
我們可以使用Java插件(譯注:關(guān)于Gradle插件的定義,請查看第一篇教程)來創(chuàng)建一個Java項目搁凸,為了做到這點媚值,我們需要把下面這段語句加入到build.gradle文件中:
apply plugin: 'java'
就是這樣,現(xiàn)在我們已經(jīng)創(chuàng)建了一個Java項目护糖。Java插件會在我們的構(gòu)建中添加一些新的約定(如默認(rèn)的項目結(jié)構(gòu))褥芒,新的任務(wù),和新的屬性嫡良。
讓我們來快速地看一下默認(rèn)的項目結(jié)構(gòu)锰扶。
Java項目結(jié)構(gòu)
默認(rèn)的項目結(jié)構(gòu)如下:
src/main/java目錄包含了項目的源代碼。
src/main/resources目錄包含了項目的資源(如屬性文件)寝受。
src/test/java目錄包含了測試類坷牛。
src/test/resources目錄包含了測試資源。所有我們構(gòu)建生成的文件都會在build目錄下被創(chuàng)建很澄,這個目錄涵蓋了以下的子目錄京闰,這些子目錄我們會在這篇教程中提到,另外還有一些子目錄我們會放在以后講解甩苛。
classes目錄包含編譯過的.class文件蹂楣。
libs目錄包含構(gòu)建生成的jar或war文件。
為構(gòu)建加入一個主類(main class)
讓我們創(chuàng)建一個簡單的主類讯蒲,在這個類中會打印一個“Hello world”然后System.out出來痊土。這個HelloWorld類的源代碼如下:
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工程中的任務(wù)旭等。
Java工程中的任務(wù)
Java插件在我們的構(gòu)建中加入了很多任務(wù)酌呆,我們這篇教程涉及到的任務(wù)如下:
assemble任務(wù)會編譯程序中的源代碼,并打包生成Jar文件搔耕,這個任務(wù)不執(zhí)行單元測試隙袁。
build任務(wù)會執(zhí)行一個完整的項目構(gòu)建。
clean任務(wù)會刪除構(gòu)建目錄度迂。
compileJava任務(wù)會編譯程序中的源代碼藤乙。
我們還可以執(zhí)行以下命令得到一個可運行任務(wù)及其描述的完整列表
> 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: Assembles the artifacts of a configuration.
Pattern: upload: Assembles and uploads the artifacts belonging to a configuration.
Pattern: clean: Cleans the output files of a task.
To see all tasks and more detail, run with --all.
BUILD SUCCESSFUL
Total time: 2.792 secs
我們繼續(xù)猜揪,下面要講怎樣打包我們的項目惭墓。
打包我們的項目
我們可以通過使用兩個不同的任務(wù)來打包項目。
如果我們在命令提示符中執(zhí)行命令gradle assemble而姐,我們可以看到以下輸出:
> gradle assemble
:compileJava
:processResources
:classes
:jar
:assemble
BUILD SUCCESSFUL
Total time: 3.163 secs
如果我們在命令提示符中執(zhí)行命令gradle build腊凶,我們可以看到以下輸出:
> gradle build
:compileJava
:processResources
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build
BUILD SUCCESSFUL
Total time: 3.01 secs
這些命令的輸出表明了它們的區(qū)別:
assemble任務(wù)僅僅執(zhí)行項目打包所必須的任務(wù)集。
build任務(wù)執(zhí)行項目打包所必須的任務(wù)集,以及執(zhí)行自動化測試钧萍。這兩個命令都會在build/libs目錄中創(chuàng)建一個file-java-project.jar文件褐缠。默認(rèn)創(chuàng)建的Jar文件名稱是由這個模版決定的:[projectname].jar,此外风瘦,項目的默認(rèn)名稱和其所處的目錄名稱是一致的队魏。因此如果你的項目目錄名稱是first-java-project,那么創(chuàng)建的Jar文件名稱就是first-java-project.jar万搔。
現(xiàn)在胡桨,我們嘗試使用以下命令運行我們的程序:
java -jar first-java-project.jar
我們可以看到以下輸出:
> java -jar first-java.project.jar
No main manifest attribute, in first-java-project.jar
問題出在,我們沒有在manifest文件中配置Jar文件的主類瞬雹,讓我們繼續(xù)看看怎樣解決這個問題昧谊。
配置Jar文件的主類
Java插件在我們的項目中加入了一個Jar任務(wù),每一個Jar對象都一個manifest屬性酗捌,這個屬性是Manifest的一個實例呢诬。
我們可以對生成的Jar文件的主類進(jìn)行配置,使用Manifest接口的attributes()方法胖缤。換句話說尚镰,我們可以使用一個包含鍵值對的map結(jié)構(gòu)指定加入到manifest文件的屬性集。
我們能夠通過設(shè)置Main-Class屬性的值草姻,指定我們程序的入口點钓猬。在我們對build.gradle文件進(jìn)行必要的改動后,代碼如下:
apply plugin: 'java'
jar {
manifest {
attributes 'Main-Class': 'net.petrikainulainen.gradle.HelloWorld'
}
}
(JavaSE教程提供了關(guān)于manifest文件的更多信息撩独。)
在我們執(zhí)行g(shù)radle assemble或gradle build命令生成一個新的jar文件之后敞曹,我們可以執(zhí)行以下命令運行jar文件:
java -jar first-java-project.jar
當(dāng)我們運行程序時,System.out會打印出以下信息:
> java -jar first-java-project.jar
Hello World!
這就是我們今天所有的內(nèi)容综膀,我們看一下我們學(xué)到了什么澳迫。