GradleUserGuide中文版 7)Java构建 8)依赖管理基础 9)Groovy入门

11 篇文章 0 订阅

7 Java 构建入门

7.1 Java 插件

Gradle 是一种多用途的构建工具. 可以在你的构建脚本里构建任何想要实现的东西. 但前提是必须先在构建脚本里加入代码, 不然它什么都不会执行.

多数 Java 项目是非常相像的: 需要编译你的 Java 源文件, 运行一些单元测试, 同时创建一个包含类文件的 JAR. 可以避免为每一个项目重复编写这些.

Gradle 通过使用插件解决了这个问题. 插件是 Gradle 的扩展, 它会通过某种方式配置你的项目, 典型的有加入一些预配置任务.
Gradle 自带了许多插件, 也可以很简单地编写自己的插件并和其他开发者分享它. Java 插件就是一个这样的插件. 这个插件在项目里加入了许多任务, 这些任务会编译和单元测试源文件, 并且把它们都集成一个 JAR 文件里.

Java 插件是基于合约的. 这意味着插件已经给项目的许多方面定义了默认的参数, 比如 Java 源文件的位置. 如果在项目里遵从这些合约, 通常不需要在构建脚本里加入太多东西.
如果不想要或者是不能遵循合约, Gradle 也允许自己定制项目.
事实上, 因为对 Java 项目的支持是通过插件实现的, 如果不想要它, 可以不用这个插件来构建你的项目.

在后面的章节, 可以深入了解 Java 插件, 依赖管理和多项目构建. 本章先来初步认识如何使用Java插件来构建一个Java项目.

7.2 一个基础的 Java 项目

7-1 使用 Java 插件
build.gradle

apply plugin: 'java'

samples/java/quickstart : 二进制代码和源代码里都包含这些文件. 它会把 Java 插件加入到项目中, 这意味着许多预定制的任务被自动加入到了项目里.

Gradle 希望能在 src/main/java 找到源代码, 在 src/test/java 找到测试代码, 即Gradle 默认地在这些路径里查找资源.
另外, 任何在 src/main/resources 的文件都将被包含在 JAR 文件里, 同时任何在 src/test/resources 的文件会被加入到 classpath 中以运行测试代码. 所有的输出文件将会被创建在构建目录里, JAR 文件存放在 build/libs 文件夹里.

都有什么可以执行的任务呢?
使用 gradle tasks 来列出项目的所有任务. 通过这个命令来看看 Java 插件在项目里加入了哪些命令.

https://downloads.gradle.org/distributions/gradle-2.9-all.zip

7.2.1 建立项目

Java 插件在你的项目里加入了许多任务. 然而, 你只会用到其中的一小部分任务. 最常用的任务是 build 任务, 它会建立你的项目. 当你运行 gradle build 命令时, Gradle 将会编译和测试你的代码, 并且创建一个包含类和资源的 JAR 文件:

7-2 建立一个 Java 项目
gradle build

> gradle build
:compileJava
:processResources
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build

BUILD SUCCESSFUL

Total time: 1 secs

其余一些有用的任务
clean
删除 build 生成的目录和所有生成的文件.

assemble
编译并打包代码, 但是并不运行单元测试. 其他插件会在这个任务里加入更多的东西. e.g. 如果使用 War 插件, 这个任务将根据项目生成一个 WAR 文件.

check
编译并测试代码. 其他的插件会加入更多的检查步骤. e.g. 如果你使用 checkstyle 插件, 这个任务将会运行 Checkstyle 来检查代码.

7.2.2 外部的依赖

通常, 一个 Java 项目有许多外部的依赖, 指外部的 JAR 文件. 为了在项目里引用这些 JAR 文件, 需要告诉 Gradle 去哪里找它们.
在 Gradle 中, JAR 文件位于一个仓库中, 这里的仓库类似于 MAVEN 的仓库. 仓库可以被用来提取依赖, 或者放入一个依赖, 或者两者皆可. e.g. 使用开放的 Maven 仓库:

7-3 加入 Maven 仓库
build.gradle

repositories {
    mavenCentral()
}

加入一些依赖. 这里, 假设项目在编译阶段有一些依赖:
7-4 加入依赖
build.gradle

dependencies {
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

commons-collections 被加入到了编译阶段, junit 也被加入到了测试编译阶段.

7.2.3 定制项目

Java 插件给项目加入了一些属性 (propertiy). 这些属性已经被赋予了默认的值, 已经足够来开始构建项目了.
如果你认为不合适, 改变它们的值也是很简单的. e.g. 这里将指定 Java 项目的版本号, 以及我们所使用的 Java 的版本. 同样也加入了一些属性在 jar 的清单里.

7-5 定制 MANIFEST.MF 文件
build.gradle

sourceCompatibility = 1.5
version = '1.0'
jar {
    manifest {
        attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
    }
}

Java 插件加入的任务是常规性的任务, 准确地说, 就如同它们在构建文件里声明地一样. 这意味着你可以使用任务之前的章节提到的方法来定制这些任务.
e.g. 可以设置一个任务的属性, 在任务里加入行为, 改变任务的依赖, 或者完全重写一个任务, 我们将配置一个测试任务, 当测试执行的时候它会加入一个系统属性:
7-6 测试阶段加入一个系统属性
build.gradle

test {
    systemProperties 'property': 'value'
}

哪些属性是可用的?
可以使用 gradle properties 命令来列出项目的所有属性. 这样就可以看到 Java 插件加入的属性以及它们的默认值.

7.2.4 发布 JAR 文件

通常 JAR 文件需要在某个地方发布. 为了完成这一步, 需要告诉 Gradle 哪里发布 JAR 文件.
在 Gradle 里, 生成的文件比如 JAR 文件将被发布到仓库里. 例子里,将发布到一个本地的目录. 你也可以发布到一个或多个远程的地点.

7-7 发布 JAR 文件
build.gradle

uploadArchives {
    repositories {
       flatDir {
           dirs 'repos'
       }
    }
}

运行 gradle uploadArchives 命令来发布 JAR 文件.

7.2.5 创建 Eclipse 项目

为了把项目导入到 Eclipse, 你需要加入另外一个插件:

7-8 Eclipse 插件
build.gradle

apply plugin: 'eclipse'

现在运行 gradle eclipse 命令来生成 Eclipse 的项目文件. Eclipse 任务 – 第 38 章 Eclipse 插件

7.2.6 总结

完整的构建文件的样本:
7-9 Java 例子 - 完整的构建文件
build.gradle

apply plugin: 'java'
apply plugin: 'eclipse'

sourceCompatibility = 1.5
version = '1.0'
jar {
    manifest {
        attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
    }
}

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

test {
    systemProperties 'property': 'value'
}

uploadArchives {
    repositories {
       flatDir {
           dirs 'repos'
       }
    }
}

7.3 多项目的 Java 构建

典型的多项目构建. 下面是项目的布局:

7-10 多项目构建 - 分层布局
构建布局

multiproject/
  api/
  services/webservice/
  shared/

samples/java/multiproject

现在我们能有三个项目. 项目的应用程序接口 (API) 产生一个 JAR 文件, 这个文件将提供给用户, 给用户提供基于 XML 的网络服务. 项目的网络服务是一个网络应用, 它返回 XML. shared 目录包含被 api 和 webservice 共享的代码.

7.3.1 定义一个多项目构建

为了定义一个多项目构建, 需要创建一个设置文件 ( settings file). 设置文件放在源代码的根目录, 它指定要包含哪个项目. 它的名字必须叫做 settings.gradle.
例子中, 我们使用一个简单的分层布局. 下面是对应的设置文件:

7-11 多项目构建 - settings.gradle file
settings.gradle

include "shared", "api", "services:webservice", "services:shared"

第56章. 多项目构建

7.3.2 通用配置

对于绝大多数多项目构建, 有一些配置对所有项目都是常见的或者说是通用的.
例子里, 我们将在根项目里定义一个这样的通用配置, 使用一种叫做配置注入的技术 (configuration injection). 这里, 根项目就像一个容器, subprojects 方法遍历这个容器的所有元素并且注入指定的配置 . 通过这种方法, 可以很容易的定义所有档案和通用依赖的内容清单:

7-12 多项目构建 - 通用配置
build.gradle

subprojects {
    apply plugin: 'java'
    apply plugin: 'eclipse-wtp'

    repositories {
       mavenCentral()
    }

    dependencies {
        testCompile 'junit:junit:4.11'
    }

    version = '1.0'

    jar {
        manifest.attributes provider: 'gradle'
    }
}

注意, Java 插件被应用到了每一个子项目中 plugin to each. 这意味着前几章看到的任务和属性都可以在子项目里被调用. 所以, 你可以通过在根目录里运行 gradle build 命令编译, 测试, 和 JAR 所有的项目.

7.3.3 项目之间的依赖

可以在同一个构建里加入项目之间的依赖, e.g. 一个项目的 JAR 文件被用来编译另外一个项目.
在 api 构建文件里我们将加入一个由 shared 项目产生的 JAR 文件的依赖. 由于这个依赖, Gradle 将确保 shared 项目总是在 api 之前被构建.

7-13 多项目构建 - 项目之间的依赖
api/build.gradle

dependencies {
    compile project(':shared')
}
7.3.4 创建一个发行版本

7-14 多项目构建 - 发行文件
api/build.gradle

task dist(type: Zip) {
    dependsOn spiJar
    from 'src/dist'
    into('libs') {
        from spiJar.archivePath
        from configurations.runtime
    }
}

artifacts {
   archives dist
}

8 依赖管理的基础知识

8.1什么是依赖管理?

粗略的讲, 依赖管理由两部分组成.
首先, Gradle 需要了解你的项目需要构建或运行的东西, 以便找到它们. 我们称这些传入的文件为项目的 dependencies(依赖项).
其次, Gradle 需要构建并上传你的项目产生的东西. 我们称这些传出的项目文件为 publications(发布项).
看看这两条的详细信息:

大多数项目都不是完全独立的. 它们需要其它项目进行编译或测试等等.
e.g. 为了在项目中使用 Hibernate, 在编译的时候需要在 classpath 中添加一些 Hibernate 的 jar 路径. 要运行测试的时候, 需要在 test classpath 中包含一些额外的 jar, 比如特定的 JDBC 驱动或者 Ehcache jars.

这些传入的文件构成上述项目的依赖. Gradle 允许你告诉它项目的依赖关系, 以便找到这些依赖关系, 并在你的构建中维护它们.
依赖关系可能需要从远程的 Maven 或者 Ivy 仓库中下载, 也可能是在本地文件系统中, 或者是通过多项目构建另一个构建. 我们称这个过程为 dependency resolution(依赖解析).

这一特性与 Ant 相比效率了许多. 使用 Ant, 你只有指定 jar 的绝对路径或相对路径才能读取 jar. 使用 Gradle, 只需要申明依赖的名称, 然后它会通过其它的设置来决定在哪里获取这些依赖关系,
e.g. 从 Maven 库. 你可以为 Ant 添加 Apache Ivy 库或得类似的方法, 但是 Gradle 做的更好.

通常, 一个项目本身会具有依赖性. e.g. 运行 Hibernate 的核心需要其他几个类库在 classpath 中.
因此, Gradle 在为你的项目运行测试的时候, 它会找到这些依赖关系, 并使其可用. 我们称之为transitive dependencies(依赖传递).

大部分项目的主要目的是要建立一些文件, 在项目之外使用. e.g. 你的项目产生一个 Java 库, 你需要构建一个jar, 可能是一个 jar 和一些文档, 并将它们发布在某处.

这些传出的文件构成了项目的发布. Gradle 会为你负责这个重要的工作. 你声明项目的发布, Gradle 会构建并发布在某处. 究竟什么是”发布”取决于你想做什么.
可能你希望将文件复制到本地目录, 或者将它们上传到一个远程 Maven 或者 Ivy 库.或者你可以使用这些文件在多项目构建中应用在其它的项目中. 我们称这个过程为 publication(发布)

8.2声明你的依赖

基础的构建脚本:
8-1 声明依赖
build.gradle

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

这个构建脚本声明 Hibernate core 3.6.7.最终 被用来编译项目的源代码.
言外之意是, 在运行阶段同样也需要 Hibernate core 和它的依赖. 构建脚本同样声明了需要 junit >= 4.0 的版本来编译项目测试. 它告诉 Gradle 到 Maven 中央仓库里找任何需要的依赖. 接下来的部分会具体说明.

8.3 依赖配置

在 Gradle 里, 依赖可以组合成configurations(配置). 一个配置简单地说就是一系列的依赖. 我们称它们为(dependency configuration)依赖配置.
可以使用它们声明项目的外部依赖. 正如我们将在后面看到, 它们也被用来声明项目的发布.

Java 插件定义了许多标准的配置. 下面列出了一些 – Table 23.5, “Java 插件 - 依赖配置”

compile
用来编译项目源代码的依赖.

runtime
在运行时被生成的类使用的依赖. 默认的, 也包含了编译时的依赖.

testCompile
编译测试代码的依赖. 默认的, 包含生成的类运行所需的依赖和编译源代码的依赖.

testRuntime
运行测试所需要的依赖. 默认的, 包含上面三个依赖.

各种各样的插件加入许多标准的配置. 也可以定义自己的配置. 参考 Section 52.3, “配置依赖”可以找到更加具体的定义和定制一个自己的依赖配置.

8.4 外部的依赖

可以声明许多种依赖. 其中一种是external dependency(外部依赖). 这是一种在当前构建之外的一种依赖, 它被存放在远程或本地的仓库里, e.g. Maven 的库, 或者 Ivy 库, 甚至是一个本地的目录.

下面的例子讲展示如何加入外部依赖
8-2 定义一个外部依赖
build.gradle

dependencies {
    compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
}

引用一个外部依赖需要使用 group, name 和 version 属性. 根据你想要使用的库, group 和 version 可能会有所差别.

有一种简写形式, 只使用一串字符串 “group:name:version”.
8-3 外部依赖的简写形式
build.gradle

dependencies {
    compile 'org.hibernate:hibernate-core:3.6.7.Final'
}

参见Section 52.4,”How to declare you dependencies”.

8.5 仓库

Gradle 是怎样找到那些外部依赖的文件的呢? Gradle 会在一个repository(仓库)里找这些文件. 仓库其实就是文件的集合, 通过 group, name 和 version 整理分类.
Gradle 能解析好几种不同的仓库形式, e.g. Maven 和 Ivy, 同时可以理解各种进入仓库的方法, 比如使用本地文件系统或者 HTTP.

默认地, Gradle 不提前定义任何仓库. 在使用外部依赖之前, 你需要自己至少定义一个库. 比如使用下面例子中的 Maven central 仓库:
8-4 Maven central 仓库
build.gradle

repositories {
    mavenCentral()
}

或者使用一个远程的 Maven 仓库:

8-5 使用远程的 Maven 仓库
build.gradle

repositories {
    maven {
        url "http://repo.mycompany.com/maven2"
    }
}

8-6 使用远程的 Ivy 仓库
build.gradle

repositories {
    ivy {
        url "http://repo.mycompany.com/repo"
    }
}

可以使用本地的文件系统里的库. Maven 和 Ivy 都支持下载到本地.

8-7 使用本地的 Ivy 目录
build.gradle

repositories {
    ivy {
        // URL can refer to a local directory
        url "../local-repo"
    }
}

一个项目可以有好几个库. Gradle 会根据依赖定义的顺序在各个库里寻找它们, 在第一个库里找到了就不会再在第二个库里找它了.

Section 50.6 章, “仓库”

8.6 发布 artifacts

依赖配置也可以用来发布文件. 我们称这些文件 publication artifacts, 或者就叫 artifacts.

插件可以很好的定义一个项目的 artifacts, 所以并不需要做一些特别的工作来让 Gradle 需要发布什么. 你可以通过在 uploadArchives 任务里加入仓库来完成. 下面是一个发布远程 Ivy 库的例子:

8-8 发布一个 Ivy 库
build.gradle

uploadArchives {
    repositories {
        ivy {
            credentials {
                username "username"
                password "pw"
            }
            url "http://repo.mycompany.com"
        }
    }
}

当运行 gradle uploadArchives, Gradle 将构建和上传 Jar. Gradle 也会生成和上传 ivy.xml .

也可以发布到 Maven 库.语法稍有不同. 请注意你需要加入 Maven 插件来发布一个 Maven 库. 在下面的例子里, Gradle 将生成和上传 pom.xml.

8-9 发布 Maven 库
build.gradle

apply plugin: 'maven'

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "file://localhost/tmp/myRepo/")
        }
    }
}

Chapter 53, Publishing artifacts

8.7 下一步?

对于依赖关系的所有细节 – Chapter 52, 依赖管理
artifact发布细节 – Chapter 53, Publishing artifacts

9 Groovy 快速入门

构建 Groovy 项目时, 需要使用 Groovy plugin (Groovy插件). 这个插件扩展了 Java 插件, 加入了编译 Groovy 的依赖. 项目可以包含 Groovy 的源代码, Java 源代码, 或者它们的混合.
在其他方面,一个Groovy项目与Java项目是相同的 – Chapter 7, Java Quickstart

9.1 一个基本的 Groovy 项目

为了使用 Groovy 插件, 加入下面的代码:
8-1 Groovy插件
build.gradle

apply plugin: 'groovy'

samples/groovy/quickstart “-all”

它会同时把 Java 插件加入到项目里. Groovy 插件扩展了编译任务, 这个任务会在 src/main/groovy 目录里寻找源代码文件, 并且加入了编译测试任务来寻找 src/test/groovy 目录里的测试源代码.
编译任务使用 联合编译 (joint compilation) 来编译这些目录, 这里的联合指的是它们混合有 java 和 groovy 的源文件.

使用 groovy 编译任务, 必须声明 Groovy 的版本和 Groovy 库的位置. 可以在配置文件里加入依赖, 编译配置会继承这个依赖, 然后 groovy 库将被包含在 classpath 里.

8-2 Groovy 2.2.0
build.gradle

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.3.3'
}

8-3 完整的构建文件
build.gradle

apply plugin: 'eclipse'
apply plugin: 'groovy'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.3.3'
    testCompile 'junit:junit:4.11'
}

运行 gradle build 命令将会开始编译, 测试和创建 JAR 文件.

9.2 总结

这一章描述了一个非常简单的 Groovy 项目. 通常, 一个真正的项目要比这个复杂的多. 因为 Groovy 项目是一个 Java 项目, 任何你可以对 Java 项目做的配置也可以对 Groovy 项目做.

Chapter 24,The Groovy Plugin; samples/groovy

—TBC—
—YCR—

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值