结合 Gradle 来构建 Java 项目

开篇词

该指南将引导你使用 Gradle 构建简单的 Java 项目。
 

你将创建的应用

你将借助 Gradle 构建一个简单的应用。
 

你将需要的工具

  • 大概 15 分钟左右;
  • 你最喜欢的文本编辑器或集成开发环境(IDE)
  • JDK 6 或更高版本;
     

如何完成这个指南

像大多数的 Spring 入门指南一样,你可以从头开始并完成每个步骤,也可以绕过你已经熟悉的基本设置步骤。如论哪种方式,你最终都有可以工作的代码。

  • 要从头开始,移步至设置项目
  • 要跳过基础,执行以下操作:
    • 下载并解压缩该指南将用到的源代码,或借助 Git 来对其进行 clone 操作:git clone https://github.com/spring-guides/gs-gradle.git
    • 切换至 gs-gradle/initial 目录;
    • 跳转至该指南的安装 Gradle

待一切就绪后,可以检查一下 gs-gradle/complete 目录中的代码。

设置项目

首先,为 Gradle 设置一个 Java 项目。为了将注意力集中在 Gradle 上,先使该项目尽可能的简单。

创建目录结构

在选择的项目目录中,创建以下自目录结构;例如,在 Linux 系统上使用 mkdir -p src/main/java/hello

└── src
    └── main
        └── java
            └── hello

src/main/java/hello 目录中,我们可以创建 Java 类。为简单起见以及与该指南的其余部分保持一致,Spring 建议创建两个类:HelloWorld.javaGreeter.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。

强烈建议使用其中一个安装程序:

当这些工具都不满足我们的需求时,我们可以从 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 能做什么

在为项目创建 build.gradle 文件之前,我们可以查看它能执行的任务都有哪些:

gradle tasks

我们应该看到可用任务列表。当我们在没有 build.gradle 文件的目录中运行 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 时,任务列表将增加,因此我们会经常查看有哪些可用的任务。

接下来我们将添加一个用以启用基本 Java 构建功能的插件:
 

构建 Java 代码

从简单开始,在该指南开头创建的 <项目文件夹> 中创建一个基本的 build.gradle 文件,它只有一行配置:

apply plugin: 'java'

这一行配置非常有用。再次运行 Gradle 任务时我们将看到任务列表中有新的任务,包括用于构建项目、创建 JavaDoc 以及运行测试的任务。

我们会经常使用 Gradle 来构建任务。该任务将编译、测试代码并将其组成为一个 JAR 文件。我们可以这样来运行它:

gradle build

几秒后,“BUILD SUCCESSFUL” 的显示表明构建已完成。

要查看构建工作的结果,请查看构建目录。我们将在其中找到几个目录,其中包括以下三个经典的目录:

  • classes:项目的已编译 .class 文件;
  • 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 来构建项目,构建将会失败,因为我们还未在构建中将 Joda Time 声明为编译时依赖。

对初学者来说,我们需要添加第三方库的源。

repositories {
    mavenCentral()
}

repositories 块指示构建应从 Maven 仓库中解析其依赖项。Gradle 在很大程度上依赖于 Maven 构建工具所建立的许多约定以及功能,包括使用 Maven 作为依赖库源头的选项。

我们已经准备好了第三方库,进行一下声明操作:

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile "joda-time:joda-time:2.2"
    testCompile "junit:junit:4.12"
}

借助于 dependencies 块,我们可以为 Joda Time 声明一个单一依赖。具体来说,我们从 joda-time 组中获取版本为 2.2 的库。

另一个需要注意的是,它是一个 compile (编译时)依赖,表明它仅在编译时可用(以及如果我们正在构建 WAR 文件时,包含至 WAR 的 /WEB-INF/libs 目录中)。其他值得注意的依赖类型包括:

  • providedCompile:编译项目代码所需的依赖,但在运行时将由运行该代码的运行容器(例如 Java Servlet API)来提供;
  • testCompile:用于编译和运行测试的依赖,但对于构建或运行项目的运行时代码时则不是必要的。

最后,我们来指定 JAR 工件的名称:

jar {
    baseName = 'gs-gradle'
    version =  '0.1.0'
}

jar 块指定了 JAR 文件的名称。这种情况下,它将被渲染为 gs-gradle-0.1.0.jar

如果我们现在运行 gradle build,Gradle 应该可以从 Maven 仓库中解析 Joda Time 的依赖并且构建将成功。

结合 Gradle Wrapper 来构建项目

Gradle Wrapper 是开始 Gradle 构建的首选方案。它由 Widows 的批处理脚本、OS X 以及 Linux 的 Shell 脚本所组成。这些脚本允许我们在无需安装 Gradle 的情况下运行 Gradle 构建。这曾经是要添加到构建文件中的内容,但已被折叠至 Gradle 中,所以不再需要进行声明。取而代之的是只需要使用以下命令:

$ gradle wrapper --gradle-version 2.13

在该任务完成之后,我们会注意到一些新文件。这两个脚本位于目录的根路径中,而包装好的 jar 以及属性文件已被添加至新的 gradle/wrapper 目录中。

└── <project folder>
    └── gradlew
    └── gradlew.bat
    └── gradle
        └── wrapper
            └── gradle-wrapper.jar
            └── gradle-wrapper.properties

现在,Gradle 包装器可以被用于构建项目。将其添加至我们的版本控制系统中,然后每一个 clone 项目的人都可以以相同的方式对其进行构建操作。它的使用方式与安装版的 Gradle 完全一致。运行包装器脚本以执行构建任务,和之前一样:

./gradlew build

在首次给指定版本的 Gradle 运行包装器时,它将下载并缓存该版本的 Gradle 二进制文件。Gradle 包装器文件旨在提交至源码控制系统,因此任何人都可以在无需先安装和配置特定版本的 Gradle 的情况下构建项目。

在该阶段,代码已构建完成,我们可以看到结果:

build
├── classes
│   └── main
│       └── hello
│           ├── Greeter.class
│           └── HelloWorld.class
├── dependency-cache
├── libs
│   └── gs-gradle-0.1.0.jar
└── tmp
    └── jar
        └── MANIFEST.MF

其中包括 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'

我们可以尝试运行该应用:

$ ./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[]

这里嵌入了许多开始/结束注释。这样就可以将构建文件的块提取到该指南中,以进行上述的详细解说。我们在生产环境的构建文件中不需要它们。

概述

恭喜你!我们创建了一个简单而有效的 Gradle 构建文件,用于构建 Java 项目。
 

参见

以下指南也可能会有所帮助:

想看指南的其他内容?请访问该指南的所属专栏:《Spring 官方指南

发布了77 篇原创文章 · 获赞 6 · 访问量 1612

猜你喜欢

转载自blog.csdn.net/stevenchen1989/article/details/104069171
今日推荐