本文带你用Gradle编译一个简单的Java项目。
创建一个简单的Java项目,然后用Gradle编译。
我们首先需要创建项目一个Java项目。为了专注于Gradle的操作,这个Java项目越简单越好。
在你选择的项目文件夹下面,创建子文件夹。
Windows系统的话,在命令行运行命令 :
mkdir src\main\java\hello
*nix系统的话,在运行命令 :
mkdir -p src/main/java/hello
最后文件夹结构如下:
└── src
└── main
└── java
└── hello
在src/main/java/hello文件夹下面,你可以按自己的想法创建任何Java类。为了简单起见,我们只创建两个类:HelloWorld.java和Greeter.java。
package hello;
public class HelloWorld {
public static void main(String[] args) {
Greeter greeter = new Greeter();
System.out.println(greeter.sayHello());
}
}
package hello;
public class Greeter {
public String sayHello(){
return "Hello world!";
}
}
现在你已经有一个可以编译的项目了,接下来我们开始安装Gradle。
我们可以用管理工具安装Gradle:
当然,如果你不想安装额外的工具软件,你可以从https://www.gradle.org/downloads上面直接下载gradle的二进制文件。我们只需要二进制文件,可以直接去找gradle-{version}-bin.zip文件来下载(例如gradle-6.5.1-bin.zip)。
下载下来之后,解压压缩包,然后把里面的bin文件夹添加到你的电脑的 高级系统设置 => 环境变量 => 系统变量 => path 里面。
为了测试Gradle是否安装成功,在你的项目根目录下面,用命令行运行命令:
gradle
如果安装成功,可以看到输出信息如下(版本号可能不同):
> Task :help
Welcome to Gradle 6.5.1.
To run a build, run gradle ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
To see more detail about a task, run gradle help --task
For troubleshooting, visit https://help.gradle.org
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed
同时,项目根目录下面多了一个 .gradle 文件夹。
现在Gradle已经安装成功了,看看它可以做什么。在你创建项目编译配置文件 build.gradle 之前,你可以看看Gradle里面有什么任务可以用,运行如下命令:
gradle tasks
你可以看到一个可用任务的列表。假设你还没有添加 build.gradle 文件,你将看到一些非常基本的任务,如下:
> Task :tasks
> Connecting to Daemon
------------------------------------------------------------
Tasks runnable from root project
------------------------------------------------------------
Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.
Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'learn-gradle'.
components - Displays the components produced by root project 'learn-gradle'. [incubating]
dependencies - Displays all dependencies declared in root project 'learn-gradle'.
dependencyInsight - Displays the insight into a specific dependency in root project 'learn-gradle'.
dependentComponents - Displays the dependent components of components in root project 'learn-gradle'. [incubating]
help - Displays a help message.
model - Displays the configuration model of root project 'learn-gradle'. [incubating]
outgoingVariants - Displays the outgoing variants of root project 'learn-gradle'.
projects - Displays the sub-projects of root project 'learn-gradle'.
properties - Displays the properties of root project 'learn-gradle'.
tasks - Displays the tasks runnable from root project 'learn-gradle'.
To see all tasks and more detail, run gradle tasks --all
To see more detail about a task, run gradle help --task
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed
尽管这些任务都是可用的,但是在没有项目编译配置文件的情况下,这些任务没有什么意义。随着你向build.gradle里面填充具体的内容,一些任务就会变得有用。
任务列表会随着你添加插件到build.gradle里面而变多,所以你偶尔可以运行tasks命令,看看都有什么任务可用。
说到添加插件,接下来我们添加一个插件,开启基本的Java编译功能。
开始很简单,在你上面创建的根目录下面新建一个 build.gradle 文件,里面只写一行代码:
apply plugin: 'java'
这简单的一行代码在编译配置里面起很大的作用。重新运行 gradle task ,我们会看到任务列表里面添加的新的任务,包括编译相关的任务,生成JavaDoc的任务和运行测试的任务。
我们将会经常使用 gradle build 任务。这个任务编译,测试和打包字节码文件到一个JAR文件。你可以在命令行里面运行:
gradle build
几秒钟之后,就会显示 “BUILD SUCCESSFUL”,说明这次编译完成了。
为了查看编译的成果,我们看一下新生成的 build 文件夹。在里面我们可以看到多个文件夹,其中值得注意的有三个文件夹:
classes文件夹里面的.class文件都是通过编译Java源代码生成的。我们可以在里面找到HelloWorld.class和Greeter.class两个文件。
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 命令,编译过程会失败(提示错误:程序包org.joda.time不存在),因为你还没有声明Joda Time库作为一个编译时的依赖。
为了添加外部依赖,首先我们需要在 build.gradle 里面添加一个第三方的仓库源,如下:
repositories {
mavenCentral()
}
repositories使编译系统从Maven Central仓库里面获取依赖库。Gradle严重依靠Maven编译工具已经建立的一些约定和工具,包括以Maven Central作为仓库源的这个选项。
现在我们已经准备好使用第三方库了,继续修改build.gradle:
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile "joda-time:joda-time:2.2"
testCompile "junit:junit:4.12"
}
在dependencies块里面,我们声明一个Joda Time的依赖。我们的要求是(从右往左看):版本为2.2,名字为joda-time的库,在joda-time组里面。
另一个需要注意的是依赖的类型是 **compile ** ,说明编译时必须可用(如果你要打包成WAR文件,会包含到WAR文件的 /WEB-INF/libs 文件夹里面)。其他的需要在意的编译类型是:
最后,我们指定一下我们的JAR文件的名称:
jar {
baseName = 'learn-gradle'
version = '0.1.0'
}
jar代码块指定了JAR文件将会怎么命名。本例中,文件名将会变为 learn-gradle-0.1.0.jar。
现在如果我们运行 gradle build 命令,Gradl会从Maven Central库中获取Joda Time依赖库,并且编译会运行成功。
Gradle Wrapper是开始一个Gradle项目的首选。它包含一个批处理脚本(在Windows中使用)和一个shell脚本(在OS X或者Linux中使用)。这些脚本使你可以不安装Gradle,也能运行一个Gradle项目。你只需要使用下面的命令:
$ gradle wrapper --gradle-version 6.5.1
执行完成之后,我们可以看到增加一些文件。两个脚本文件在根目录下面,而wrapper的jar包和properties文件则被添加到了gradle/wrapper文件下面。如下所示:
└──
└── gradlew
└── gradlew.bat
└── gradle
└── wrapper
└── gradle-wrapper.jar
└── gradle-wrapper.properties
Gradle Wrapper已经可以用来编译我们的项目了。我们还可以把项目添加到版本控制系统中,而其他人可以复制你的项目然后编译它。使用Gradle Wrapper和安装了相同版本的Gradle的效果一样。运行wrapper脚本来执行编译任务,就像上面的操作那样:
gradlew build
或者
./gradlew build
控制台输出结果如下:
Downloading https://services.gradle.org/distributions/gradle-6.5.1-bin.zip
.........10%..........20%..........30%..........40%.........50%..........60%..........70%..........80%.........90%..........100%
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 1m 21s
2 actionable tasks: 2 up-to-date
在上面我们用–gradle-version设置了Gradle版本为6.5.1,所以Gradle首先下载并缓存了这个版本的Gradle二进制文件(如果已经缓存过,会直接使用缓存)。
Gradle Wrapper的设计目的就是为了直接提交到源码控制系统里面,使任何人都可以直接编译项目,而不用先安装Gradle再编译项目。同时可以配置使用特定版本的Gradle。
现在,你可以看到编译的成果如下:
├─classes
│ └─java
│ └─main
│ └─hello
│ Greeter.class
│ HelloWorld.class
│
├─generated
│ └─sources
│ ├─annotationProcessor
│ │ └─java
│ │ └─main
│ └─headers
│ └─java
│ └─main
├─libs
│ learn-gradle-0.1.0.jar
│
└─tmp
├─compileJava
│ source-classes-mapping.txt
│
└─jar
MANIFEST.MF
在里面,有我们所期望的class文件Greeter.class和HelloWorld.class,同时还有一个JAR文件。快速浏览一下JAR文件的内容:
$ jar tvf build\libs\learn-gradle-0.1.0.jar
0 Sun Jul 12 16:43:56 CST 2020 META-INF/
25 Sun Jul 12 14:52:16 CST 2020 META-INF/MANIFEST.MF
0 Sun Jul 12 16:43:56 CST 2020 hello/
369 Sun Jul 12 16:43:56 CST 2020 hello/Greeter.class
987 Sun Jul 12 16:43:56 CST 2020 hello/HelloWorld.class
我们可以看到class文件已经被打包进去了。还有重要的一点,尽管你已经声明了joda-time库的依赖,但是这个库并没有包含到JAR文件里面。而且,这个JAR文件也不能执行。
为了使代码可以执行,我们可以使用gradle’s Gradle的 application 插件。添加如下代码到build.gradle里面:
apply plugin: 'application'
mainClassName = 'hello.HelloWorld'
接下来你可以运行程序了!运行命令:
gradlew run
或者
./gradlew run
结果如下:
> Task :run
The current local time is:17:55:34.598
Hello world!
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 2s
2 actionable tasks: 1 executed, 1 up-to-date
如果要打包项目里面的依赖包,需要对应的插件。比如说,我们打包成一个WAR文件,我们可以使用Gradle的WAR插件。如果我们使用Spring Boot,并且想要一个可执行的JAR文件的话,spring-boot-gradle-plugin这个插件就很方便满足我们的要求。具体操作就不在这一章中展开了。
整理之后,最终的 build.gradle 如下:
apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'hello.HelloWorld'
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile "joda-time:joda-time:2.2"
testCompile "junit:junit:4.12"
}
jar {
baseName = 'learn-gradle'
version = '0.1.0'
}
你已经创建了一个简单但是有效的Gradle编译配置文件,可以正常的编译Java项目了。
learn-gradle
https://spring.io/guides/gs/gradle/