在现实生活中,要创造一个没有任何外部依赖的应用程序并非不可能,但也是极具挑战的。这也是为什么依赖管理对于每个软件项目都是至关重要的一部分。

这篇教程主要讲述如何使用Gradle管理我们项目的依赖,我们会学习配置应用仓库以及所需的依赖,我们也会理论联系实际,实现一个简单的演示程序。

Gradle支持以下仓库格式:

在构建中加入Maven仓库

我们可以通过URL地址或本地文件系统地址,将Maven仓库加入到我们的构建中。

如果想通过URL地址添加一个Maven仓库,我们可以将以下代码片段加入到build.gradle文件中:

repositories {
maven {
url "http://maven.petrikainulainen.net/repo"
}
}

如果想通过本地文件系统地址添加一个Maven仓库,我们可以将以下代码片段加入到build.gradle文件中:

repositories {
maven {
url “../maven-repo”
}
}

在加入Maven仓库时,Gradle提供了三种“别名”供我们使用,它们分别是:

    • mavenCentral()别名,表示依赖是从Central Maven 2 仓库中获取的。
    • jcenter()别名,表示依赖是从Bintary’s JCenter Maven 仓库中获取的。
    • mavenLocal()别名,表示依赖是从本地的Maven仓库中获取的。

如果我们想要将Central Maven 2 仓库加入到构建中,我们必须在build.gradle文件中加入以下代码片段:

repositories {
mavenCentral()
}

依赖管理简介

在配置完项目仓库后,我们可以声明其中的依赖,如果我们想要声明一个新的依赖,可以采用如下步骤:

    1. 指定依赖的配置。
    2. 声明所需的依赖。

让我们看一下详细步骤:

配置中的依赖分类

在Gradle中,依赖是按照指定名称进行分类的,这些分类被称为配置项,我们可以使用配置项声明项目的外部依赖。

Java插件指定了若干依赖配置项,其描述如下:

    • 当项目的源代码被编译时,compile配置项中的依赖是必须的。
    • runtime配置项中包含的依赖在运行时是必须的。
    • testCompile配置项中包含的依赖在编译项目的测试代码时是必须的。
    • testRuntime配置项中包含的依赖在运行测试代码时是必须的。
    • archives配置项中包含项目生成的文件(如Jar文件)。
    • default配置项中包含运行时必须的依赖。

我们继续,下面是如何在项目中声明依赖。

声明项目依赖

最普遍的依赖称为外部依赖,这些依赖存放在外部仓库中。一个外部依赖可以由以下属性指定:

    • group属性指定依赖的分组(在Maven中,就是groupId)。
    • name属性指定依赖的名称(在Maven中,就是artifactId)。
    • version属性指定外部依赖的版本(在Maven中,就是version)。

小贴士:这些属性在Maven仓库中是必须的,如果你使用其他仓库,一些属性可能是可选的。打个比方,如果你使用Flat directory仓库,你可能只需要指定名称和版本

我们假设我们需要指定以下依赖:

    • 依赖的分组是foo
    • 依赖的名称是foo
    • 依赖的版本是0.1
    • 在项目编译时需要这些依赖。

我们可以将以下代码片段加入到build.gradle中,进行依赖声明:

dependencies {
compile group: 'foo', name: 'foo', version: '0.1'
}

我们也可以采用一种快捷方式声明依赖:[group]:[name]:[version]。如果我们想用这种方式,我们可以将以下代码段加入到build.gradle中:

dependencies {
compile 'foo:foo:0.1'
}

我们也可以在同一个配置项中加入多个依赖,传统的方式如下:

dependencies {
compile (
[group: 'foo', name: 'foo', version: '0.1'],
[group: 'bar', name: 'bar', version: '0.1']
)
}

如果采用快捷方式,那可以是这样:

dependencies {
compile 'foo:foo:0.1', 'bar:bar:0.1'
}

自然地,声明属于不同配置项的依赖也是可以的。比如说,如果我们想要声明属于compiletestCompile配置项的依赖,可以这么做:

dependencies {
compile group: 'foo', name: 'foo‘, version: '0.1'
testCompile group: 'test', name: 'test', version: '0.1'
}

同样的,给力的快捷方式又来了:

dependencies {
compile 'foo:foo:0.1'
testCompile 'test:test:0.1'
}

创建演示程序

演示程序的需求是这样的:

    • 演示程序的构建脚本必须使用Maven central仓库。
    • 演示程序必须使用Log4j写入日志。
    • 演示程序必须包含包含单元测试,保证正确的信息返回,单元测试必须使用JUnit编写。
    • 演示程序必须创建一个可执行的Jar文件。

我们来看一下怎样实现这些需求。

配置仓库

我们的演示程序的一个需求是构建脚本必须使用Maven central仓库,在我们使用Maven central仓库配置构建脚本后,源代码如下:

apply plugin: 'java'

repositories {
mavenCentral()
} jar {
manifest {
attributes 'Main-Class': 'com.wuchao.gradle.HelloWorld'
}
}

我们再来看一下如何对我们的演示程序进行依赖声明。

依赖声明

build.gradle文件中,我们声明了两个依赖:

在我们声明了这些依赖后,build.gradle文件是这样的:

apply plugin: 'java'

repositories {
mavenCentral()
} dependencies {
compile 'log4j:log4j:1.2.17'
testCompile 'junit:junit:4.11'
} jar {
manifest {
attributes 'Main-Class': 'com.wuchao.gradle.HelloWorld'
}
}

我们继续,稍微加入一些代码。

编写代码

为了实现我们演示程序的需求,“我们不得不过度工程化一下”,我们会按照下列步骤创建程序:

    1. 创建一个MessageService类,当其中的getMessage()方法被调用时,返回字符串“Hello World!”。
    2. 创建一个MessageServiceTest类,确保MessageService类中的getMessage()方法返回字符串“Hello World!”。
    3. 创建程序的主类,从MessageService对象获取信息,并使用Log4j写入日志。
    4. 配置Log4j。

我们按部就班的操作一下。

首先,src/main/java/com/wuchao/gradle目录下新建一个MessageService类并加以实现,代码如下:

package com.wuchao.gradle;

public class MessageService {

    public String getMessage() {
return "Hello World!";
}
}

其次,src/test/java/com/wuchao/gradle目录下新建一个MessageServiceTest类,编写单元测试,代码如下:

package com.wuchao.gradle;

import org.junit.Before;
import org.junit.Test; import static org.junit.Assert.assertEquals; public class MessageServiceTest { private MessageService messageService; @Before
public void setUp() {
messageService = new MessageService();
} @Test
public void getMessage_ShouldReturnMessage() {
assertEquals("Hello World!", messageService.getMessage());
}
}

第三,src/main/java/com/wuchao/gradle目录下新建一个HelloWorld类,这是程序的主类,从MessageService对象获取信息,并使用Log4j写入日志,代码如下:

package com.wuchao.gradle;

import org.apache.log4j.Logger;

public class HelloWorld {

    private static final Logger LOGGER = Logger.getLogger(HelloWorld.class);

    public static void main(String[] args) {
MessageService messageService = new MessageService(); String message = messageService.getMessage();
LOGGER.info("Received message: " + message);
}
}

第四,src/main/resources目录中,使用log4j.properties配置log4j,log4j.properties文件如下:

log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n log4j.rootLogger=DEBUG,Stdout

这样就好了,我们看看如何执行测试。

gradle test

当测试通过时,我们能看到如下输出:

:compileJava
:processResources
:classes
:compileTestJava
Download https://jcenter.bintray.com/junit/junit/4.11/junit-4.11.pom
Download https://jcenter.bintray.com/junit/junit/4.11/junit-4.11.jar
:processTestResources UP-TO-DATE
:testClasses
:testPicked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=gasp BUILD SUCCESSFUL Total time: 5.9 secs

当我们执行单元测试时,Gradle会在相应目录创建测试报告:

    • build/test-results目录包含每次测试执行的原始数据。
    • build/reports/tests目录包含一个HTML报告,描述了测试的结果。

HTML测试报告是一个非常有用的工具,因为它描述了测试失败的原因。比如说,如果我们的单元测试认为MessageService类中的getMessage()方法返回字符串“Hello World0!”,那么HTML报告看上去就像下图一样:

我们继续,下面是如何打包和运行我们的演示程序。

打包和运行程序

我们能够可以使用以下任意一种命令打包程序:gradle assemblygradle build,这两个命令都会在build/libs目录中创建dependency-management.jar文件。

当我们使用java -jar dependency-management.jar命令运行演示程序时,我们可以看到如下输出:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
at com.wuchao.gradle.HelloWorld.<clinit>(HelloWorld.java:6)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more

抛出异常的原因是,当我们运行程序时,Log4j的依赖在classpath中没有找到。

解决这个问题最简单的方式是创建一个所谓的“胖”Jar文件,即把所有程序运行所需的依赖都打包到Jar文件中去。

通过查阅Gradle Cookbook中的教程,可以修改构建脚本,如下:

apply plugin: 'java'

repositories {
mavenCentral()
} dependencies {
compile 'log4j:log4j:1.2.17'
testCompile 'junit:junit:4.11'
} jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
manifest {
attributes 'Main-Class': 'net.petrikainulainen.gradle.HelloWorld'
}
}

现在,我们可以运行演示程序了(打包后),一切正常:

wuchao@wuchao-PC:~/workspace/GradleWorkSpace/dependency-management/build/libs$ java -jar dependency-management.jar
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=gasp
INFO - HelloWorld - Received message: Hello World!

Gradle入门(4):依赖管理的更多相关文章

  1. 廖雪峰Java12maven基础-1maven入门-2依赖管理

    maven 如果我们的项目依赖第三方的jar包: Commons Logging发布的jar包在那里下载? 使用Log4j需要哪些jar包 其他依赖:junit,Javamail,MySQL驱动... ...

  2. Gradle 1.12用户指南翻译——第五十章. 依赖管理

    本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见:http://blog.csdn.net/column/details/gradle-translation.html翻译项目请关注Github上 ...

  3. Java Gradle入门指南之依赖管理(添加依赖、仓库、版本冲突)

        开发任何软件,如何管理依赖是一道绕不过去的坎,软件开发过程中,我们往往会使用这样那样的第三方库,这个时候,一个好的依赖管理就显得尤为重要了.作为一个自动构建工作,Gradle对依赖管理有着很好 ...

  4. 【系列教程1】Gradle入门系列三:依赖管理

    在现实生活中,要创造一个没有任何外部依赖的应用程序并非不可能,但也是极具挑战的.这也是为什么依赖管理对于每个软件项目都是至关重要的一部分. 这篇教程主要讲述如何使用Gradle管理我们项目的依赖,我们 ...

  5. Gradle for Android 第三篇( 依赖管理 )

    依赖管理 这会是一个系列,所以如果你还没有看我之前的几篇文章,请先查看以下文章: Gradle for Android 第一篇( 从 Gradle 和 AS 开始 ) Gradle for Andro ...

  6. 在Eclipse中使用建立使用Gradle做依赖管理的Spring Boot工程

    前述: Gradle存在很长时间了,以前只知道Maven和ivy ,最近才知道有这个存在,因为以后要用这个了; 所以,要先学会怎么用这个工具,就从建立一个简单工程开始! 实际上以前是见过Gradle的 ...

  7. Gradle Maven 依赖管理

    仓库管理简介 本质上说,仓库是一种存放依赖的容器,每一个项目都具备一个或多个仓库. Gradle支持以下仓库格式: Ivy仓库 Maven仓库 Flat directory仓库 我们来看一下,对于每一 ...

  8. Liferay7 BPM门户开发之43: Gradle依赖管理

    进入liferay v7.0,官方推荐使用Gradle进行依赖管理和发布,所以必须知道Gradle的用法,网上资料很多,不赘述 只写依赖管理的分类 一般用外部仓库依赖,也可以用本地文件依赖(依赖本地j ...

  9. Gradle学习系列之七——依赖管理

    在本系列的上篇文章中,我们讲到了如何使用java Plugin,在本篇文章中,我们将讲到Gradle的依赖管理. 请通过以下方式下载本系列文章的Github示例代码: git clone https: ...

随机推荐

  1. [转]Docker 生产环境之配置容器 - 限制容器资源

    默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的给定资源.Docker 提供了一些方法来控制容器可以使用多少内存.CPU 或块 IO,并设置 docker run 命令的运行时配置标志.本 ...

  2. Codeforces VK Cup 2018 Div.2

    总题面传送门 这次考试只过了3题,前三题题目难度并不大,但是第三题的代码细节卡了我两个半小时(基本上整场考试),所以以后要合理把握时间,注意把握代码细节,并更加完善我的代码风格,使其更加简练.(赛外话 ...

  3. Codeforces 908 D.New Year and Arbitrary Arrangement (概率&期望DP)

    题目链接:New Year and Arbitrary Arrangement 题意: 有一个ab字符串,初始为空. 用Pa/(Pa+Pb)的概率在末尾添加字母a,有 Pb/(Pa+Pb)的概率在末尾 ...

  4. python爬虫之requests库介绍(二)

    一.requests基于cookie操作 引言:有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取张三“人人网”个人主页数据)时,如果使用之前requests模块常规操作时,往往达不到我们 ...

  5. SQL Server 查询请求

    当SQL Server 引擎接收到用户发出的查询请求时,SQL Server执行优化器将查询请求(Request)和Task绑定,并为Task分配一个Workder,SQL Server申请操作系统的 ...

  6. Python 的AES加密与解密-需要安装的模块

    踩雷1: #先导入所需要的包 pip3 install Crypto #再安装pycrtpto pin3 install pycrypto from Crypto.Cipher import AES ...

  7. CentOS安装Zabbix Agent

    rpm -i http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch.rpm安装存储库 yum ...

  8. charles工具教程

    本文的内容主要包括: Charles 的简介 如何安装 Charles 将 Charles 设置成系统代理 Charles 主界面介绍 过滤网络请求 截取 iPhone 上的网络封包 截取 Https ...

  9. 【SIKIA计划】_04_C#中级教程 (2015版)笔记

    IKIC#中级教程 (2015版)正常模式指的是不会影响程序的正常运行.1,在VS中我们使用Console.Write(或者WriteLine)方法向控制台输出变量的值,通过这个我们可以查看变量的值是 ...

  10. Linux系统下搭建FTP/SFTP服务器

    传输文件经常使用ftp和sftp服务器.Windows下有多种可视化工具,使用快捷.Linux经常需要自行搭建这两种服务器,当然搭建熟练的话,会更加快捷. 1.检查Linux系统是否安装了vsftp和 ...