使用Gradle构建Java项目
这个指南将指导你如何使用Gradle构建一个简单的Java项目
你将构建什么
你将创建一个简单的项目,由Gradle构建。
你需要什么
- 大约15分钟
- 一个你喜爱的文本编辑器或者IDE
- JDK 6 或者 往后至最新的JDK
怎么完整走完这个指南
就像很多Spring入门指南,你可以从零开始,一步一个脚印实现,或者你可以跳过你熟悉的步骤,不管怎么样,你最后会得到可以工作的代码。
移步到++设置项目++,从头开始
做以下步骤以跳过基本教程:
- ++下载++并且解压本指南的源代码仓库,或者使用Git克隆
git clone https://github.com/spring-guides/gs-gradle.git
- cd进入
gs-gradle/initial
- 跳到 Install Gradle
当你完成上面的步骤,你可以那你得到的结果与
gs-gradle/complete
里的代码对比。
设置项目
首先,为Gradle设置一个java项目来构建。为了把重点放在Gradle,我们尽量地把例子做得简单。
创建目录结构
在一个由你选择的项目文件夹,创建以下子目录机构;例如,在类unix系统运行
mkdir -p src/main/java/hello
└── src
└── main
└── java
└── hello
在 src/main/java/hello 目录里,你可以自由新建Java类。为了简单的缘故和为了下文的操作保持一致性,Spring推荐你创建两个类:==HelloWorld.java== 和 ==Greeter.java.==
==src/main/java/hello/HelloWorld.java==
package hello;
public class HelloWorld {
public static void main(String[] args) {
Greeter greeter = new Greeter();
System.out.println(greeter.sayHello());
}
}
==src/main/java/hello/Greeter.java==
package hello;
public class Greeter {
public String sayHello() {
return "Hello world!";
}
}
安装Gradle
既然现在有了一个可以使用Gradle构建的项目,那么接着安装Gradle
强烈推荐使用安装器:
- SDKMAN
- Homebrew(brew install gradle)
如果以上工具都不适用于你的情况,你可以从 https://www.gradle.org/downloads 下载二进制文件,这是最后的手段。只有二进制文件是不可缺的,所以请查找指向gradle-version-bin.zip的链接。(也可以选择gradle-version-all.zip以获取源代码和文档以及二进制文件。)
解压缩下载的文件,并且把bin文件夹加入到环境变量。
运行Gradle,测试Gradle的安装是否成功(项目文件夹内)。使用以下命令。
gradle
如果一切顺利,会看到一个欢迎信息:
:help
Welcome to Gradle 2.3.
To run a build, run gradle <task> ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
BUILD SUCCESSFUL
Total time: 2.675 secs
那么你现在就已经安装好Gradle了。
看看Gradle能做什么
既然现在Gradle已经安装好了,那就看看它能做什么。在你创建一个项目的build.gradle文件时,你可以查看它有哪些任务是可用的。
gradle tasks
你应该看到一个可用任务列表。假设你运行Gradle在一个没有build.gradle文件的文件夹,你会看见一些非常基础的任务,例如:
:tasks
== All tasks runnable from root project
== Build Setup tasks
setupBuild - Initializes a new Gradle build. [incubating]
== Help tasks
dependencies - Displays all dependencies declared in root project 'gs-gradle'.
dependencyInsight - Displays the insight into a specific dependency in root project 'gs-gradle'.
help - Displays a help message
projects - Displays the sub-projects of root project 'gs-gradle'.
properties - Displays the properties of root project 'gs-gradle'.
tasks - Displays the tasks runnable from root project 'gs-gradle'.
To see all tasks and more detail, run with --all.
BUILD SUCCESSFUL
Total time: 3.077 secs
即使这些任务可以使用,没有一个项目构建配置,他们没有多大的价值。当你提供了build.gradle文件,一些任务变得更有用。当你向build.gradle加入插件,任务列表会变长,所以你会有时会想再次运行 task 来看那些任务可用。
说到加入插件,下一步是加入一个启用基本java构建功能的插件。
构建java代码
从简单开始,创建一个最基础的build.gradel文件到项目文件夹,这个文件夹是你在指南开头创建的。在文件中只需写入一行代码:
apply plugin: 'java'
在构建配置中的这一行代码带来了非常有用的作用。再次运行 gradle tasks,会看到新的任务加入了这个列表,包括构建项目,创建JavaDoc,运行测试的任务。
你将经常使用 gradle build 任务。这个任务编译,测试,组装代码到一个JAR文件。你可以运行以下命令来使用:
gradle build
等待几秒,“BUILD SUCCESSFUL”说明构建已经完成。
请检查 build 文件夹,查看构建工作的结果。在其中你会找到一系列的文件夹,包括以下三个值得注意的文件夹。
- classes。此项目的已编译的.class文件。
- reports。该文件夹由build生成(比如test reports)
- libs。整合的项目的库(通常是JAR或者WAR文件)。
classes 文件夹包含 从Java代码编译出来的.class文件。特别地,你应该在里面找HelloWorld.class和Greeter.class.
在此刻,这个项目没有任何库依赖,所以在dependency_cache文件夹中没有任何文件。
reports 文件夹应包含一个项目的运行时单元测试报告。因为这个项目还没有单元测试,所以这个报告不会有趣。
libs 文件夹应包含一个以项目文件夹名字命名的JAR文件。再向下,你将看见你如何指定JAR文件名和它的版本的方法
声明依赖
这个简单的Hello World例子是完全地独立和不依赖任何额外的库。然而,很多应用依赖于外部的库来处理通常的或者复杂的功能。
举个例子,假设除了说“Hello,World”之外,你想要这个应用打印当前日期和时间,你应当使用原生java库里的日期和时间工具,不过你也可以使用Joda Time库使得它更有趣。
首先,编辑 HelloWorld.java 如以下:
package hello;
import org.joda.time.LocalTime;
public class HelloWorld {
public static void main(String[] args) {
LocalTime currentTime = new LocalTime();
System.out.println("The current local time is: " + currentTime);
Greeter greeter = new Greeter();
System.out.println(greeter.sayHello());
}
}
这里的HelloWorld使用了Joda Time的LocalTime类来获得和打印当前时间
如果你现在运行gradle build 来构建项目,那么它会失败,因为你还没有声明Jada Time 作为这次构建的编译依赖
对于初学者,需要为第三方库加入源。
repositories {
mavenCentral()
}
repositories代码块指示了这次构建应该从Maven Central 库中解决它的依赖关系。Gradle严重依赖由Maven 构建工具创建的规范和功能,包括使用Maven Central的可选项当作库依赖的源。
既然我们已经加入了第三方库,那么让我们声明他们。
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile "joda-time:joda-time:2.2"
testCompile "junit:junit:4.12"
}
根据dependencies代码块,你声明一个Joda Time的单一的依赖。特别地,你请求的是joda-time组中的joda-time库的2.2版本。
关于这个依赖有一点值得注意,就是它是一个compile依赖,说明了在compole-time过程中它可能是可用的(如果你正在构建一个WAR文件,包括这个WAR的/WEB-INF/libs文件夹)另外值得注意的依赖类型包括:
- providedCompile。编译代码所必要的依赖,但是它由一个运行这代码的容器在运行时提供的(例如,Java Servlet API)
- testCompole。被用来编译和运行测试的依赖,但是对于构建或运行项目的运行时代码是非必须的。
最后,让我们指定我们JAR成品的名字。
jar {
baseName = 'gs-gradle'
version = '0.1.0'
}
jar代码块决定这个JAR将怎样被命名,在这里,它的名字是gs-gradle-0.1.0.jar。
现在如果你运行gradle build,Gradle应该会从Maven Central仓库中解决Joda Time的依赖并且构建将会成功。
使用Gradle Wrapper 构建你的项目
Gradle Wrapper是启动一个Gradle build的首选方法。它由windows批处理脚本和OSX、Linux的shell脚本组成。这些脚本允许你无需在你的系统中安装Gradle即可运行一个Gradle build。这些原本是被添加到build文件的东西,现在他们已经被包含在Gradle里,所以不再有任何额外的要求。简单地使用以下命令:
gradle wrapper --gradle-version 2.13
在任务执行完后,会出现一些新文件,当wrapper jar和properties文件被加入到一个新的==gradle/wrapper==文件夹,这两个脚本在最上层的文件夹(root of the folder)
└── <project folder>
└── gradlew
└── gradlew.bat
└── gradle
└── wrapper
└── gradle-wrapper.jar
└── gradle-wrapper.properties
现在可以用Gradle Wrapper来构建你的项目了。把它加入到你的版本控制系统,每个克隆你项目的人就可以以同样的配置构建它了。它的使用方法同==安装版本的Gradle==一样。运行wrapper脚本来进行构建任务,就像你之前做的:
./gradlew build
第一次运行Gradle的某版本的wrapper,它会下载和缓存该版本的的Gradle二进制文件。Gradle Wrapper 文件设计为已经被提交到了资源控制,这样子不必每个人安装和配置Gradle的某个版本,来构建项目。
在这个阶段,你将编写你的代码,你会在这看到结果。
build
├── classes
│ └── main
│ └── hello
│ ├── Greeter.class
│ └── HelloWorld.class
├── dependency-cache
├── libs
│ └── gs-gradle-0.1.0.jar
└── tmp
└── jar
└── MANIFEST.MF
包括两个预期的class文件:Greeter和HelloWorld,还有JAR文件。快速预览:
$ jar tvf build/libs/gs-gradle-0.1.0.jar
0 Fri May 30 16:02:32 CDT 2014 META-INF/
25 Fri May 30 16:02:32 CDT 2014 META-INF/MANIFEST.MF
0 Fri May 30 16:02:32 CDT 2014 hello/
369 Fri May 30 16:02:32 CDT 2014 hello/Greeter.class
988 Fri May 30 16:02:32 CDT 2014 hello/HelloWorld.class
这些类文件被绑在了一起。需要非常注意的是,即使你声明了joda-time作为依赖,此处也不会有该类库。而且JAR文件也不可运行。
为了使这些代码可以运行,我们可以使用gradle的application补丁。把它加入到你的build.gradle文件
apply plugin: 'application'
mainClassName = 'hello.HelloWorld'
然后就可以把app跑起来了。
$ ./gradlew run
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
The current local time is: 16:16:20.544
Hello world!
BUILD SUCCESSFUL
Total time: 3.798 secs
打包依赖需要更多的考虑。比如说,如果我们要打包一个WAR包(一种格式,通常关联到第三方依赖的打包),我们可以使用gradle的 WAR 插件,如果你正使用SpringBoot而且想得到一个可运行的JAR文件,使用spring-boot-gradle-plugin是非常方便的。在这一步中,gradle对你的系统并不够了解,无法做出选择,不过现在,使用gradle让它跑起来是足够了的。
要完成本指南的内容,这里有已完成的build.gradle文件:
build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'
mainClassName = 'hello.HelloWorld'
// tag::repositories[]
repositories {
mavenCentral()
}
// end::repositories[]
// tag::jar[]
jar {
baseName = 'gs-gradle'
version = '0.1.0'
}
// end::jar[]
// tag::dependencies[]
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile "joda-time:joda-time:2.2"
testCompile "junit:junit:4.12"
}
// end::dependencies[]
// tag::wrapper[]
// end::wrapper[]