Gradle

Gradle

(1) 如何配置代理

将文件 gradle.properties 放在项目根目录下或者 ~/.gradle/ 下即可配置代理:

1
2
3
4
systemProp.http.proxyHost=proxy.yourproxysite.com
systemProp.http.proxyPort=8080
systemProp.https.proxyHost=proxy.yourproxysite.com
systemProp.https.proxyPort=8080

放在项目根目录下面的 gradle.properties 发挥的是单独为这个项目代理的功能,而放到 ~/.gradle/ 下配置的是 Gradle 的全局代理。 Gradle 运行的时候优先在本项目查找,其次才是全局代理。

(2) 默认依赖缓存位置

1
~/.gradle/caches/

(3) 强制下载所有依赖

1
2
# The --refresh-dependencies option tells Gradle to ignore all cached entries for resolved modules and artifacts
./gradlew build --refresh-dependencies

可用 API

Project

build.gradle 文件中设置描述信息:

1
2
setDescription("myProject")
println "Description of project $name: " + project.description
声明变量
  • 方法一: 使用 ext 命名空间
1
2
3
4
5
6
7
8
9
ext {
a = 123
}

println project.a // 123
println project.ext.a // 123
println a // 123
println "$a" // 123
println $a // ERROR
  • 方法二: 使用 gradle.properties

在文件 gradle.properties 中声明变量:

1
b = 456

然后在文件 build.gradle 中直接引用:

1
2
3
4
5
println project.b // 456
println project.ext.b // 456
println b // 456
println "$b" // 456
println $b // ERROR

注意,带有前缀 $ 符号的变量必须使用 “” 括起来:

1
2
3
4
5
6
task printProperty << {
println $a // ERROR
println $b // ERROR
println "$a" // OK
println "$b" // OK
}

Task

dependsOn

build.gradle 文件中声明任务依赖:

1
2
3
4
5
6
7
8
task first << { println "first" }
task second << { println "second" }
task printVersion(dependsOn: [second, first]) << {
logger.quiet "Version: $version"
}

task third << { println "third" }
third.dependsOn('printVersion')
type

每一个任务都有一个类型,几个重要的 type 如下:

  • DefaultTask: 默认
  • Copy: 拷贝文件
  • Jar: 从源码创建一个 Jar
  • JavaExec: 运行带有 main() 方法的 Java

依赖管理

build.gradle 文件中,我们可以对依赖进行分组,一组依赖可以放到一个 configuration 中,多组依赖可以放到一个 configurations 块中。如下代码所示,我们定义了两个 configuration,每个 configuration 都必须至少包含一个 name:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
configurations {
// 这个 configuration 的 name 是 commonsLib
commonsLib {
description = 'Common libraries'
}

// 这个 configuration 的 name 是 mainLib
mainLib {
description = 'Main libraries'
extendsFrom commonsLib
}
}

println configurations['mainLib'].name
println configurations.commonsLib.name

执行命令: gradle dependencies 我们可以查看当前所有的 configuration :

许多插件都会往 ConfigurationContainer 添加新的 configuration,例如我们使用 (apply plugin: 'java') 了 java 插件以后,我们的 configuration 也会变多:

1. 外部模块依赖

定义依赖的通用写法如下:

1
2
3
dependencies {
configurationName dependencyNotation1, dependencyNotation2, ...
}

像下面的这个例子,我们使用了 Java 插件,所以我们得到了 compileruntime 两个依赖配置,我们可以使用不同的语法格式来为每一个配置添加依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apply plugin: 'java'
repositories {
mavenCentral()
}
ext {
springVersion = '3.1.1.RELEASE'
springGroup = 'org.springframework'
}
dependencies {
// 详细写法
compile group: springGroup, name: 'spring-core', version: springVersion
// 快捷写法
runtime "$springGroup:spring-aop:$springVersion"
}
仓库
1
2
3
4
5
6
7
8
9
10
11
repositories {
mavenLocal()
mavenCentral()
// 自定义 Maven 仓库位置
maven {
// Name is optional. If not set url property is used
name = 'Main Maven repository'
url = 'http://intranet/repo'
}
mavenRepo(name: 'Snapshot repository', url: 'http://intranet/snapshots')
}

配置阿里云 Maven 仓库:

1
2
3
4
5
repositories {
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
}
}

2. 项目依赖

(1) 一般来说,gradle 如果有子项目的话,那么项目目录通常会这么组织:

我们通过在文件 settings.gradle 中声明:

1
2
3
include 'model'
include 'repository'
include 'web'

这样执行 gradle projects 的时候,我们可以看见所有的子项目。build.gradle 文件一般而言,就是定义子项目共有行为的,例如为所有的子项目添加 Java 插件:

1
2
3
4
5
6
7
8
9
10
// build.gradle 文件

allprojects {
group = 'com.manning.gia'
version = '0.1'
}

subprojects {
apply plugin: 'java'
}

子项目之间相互依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 子项目 repository 的 build.gradle 文件
dependencies {
compile project(':model')
}

// 子项目 web 的 build.gradle 文件
apply plugin: 'war'
apply plugin: 'jetty'

repositories {
mavenCentral()
}

dependencies {
compile project(':repository')
providedCompile 'javax.servlet:servlet-api:2.5'
runtime 'javax.servlet:jstl:1.1.2'
}

其中 :repository 中的 : 表示的是目录,也就是说如果你想要添加一个嵌套更深的子项目 (例如相对于 root 的位置在 /model/todo/items) 可以像下面这样声明:

1
include 'model:todo:items'

(2) 如果是两个互相独立的项目依赖的话:

需要声明所依赖的项目的位置:

1
2
include ':Dependency'
project(':Dependency').projectDir = new File(settingsDir, '../Dependency')

(3) Gradle 依赖 Maven:

You can’t really add the Maven multi-module project structure as a dependency directly. You can, however, build the multi-module project using mvn install to install the project jars to your local repository.

Then, in your build.gradle, you need the following configuration:

1
2
3
repositories {
mavenLocal()
}

This will add your local Maven repository to the list of code repositories that Gradle will look through for your artifacts. You can then declare a dependency on the module(s) that your Gradle project requires.

1
2
3
4
dependencies {
compile 'my-group:my-artifact:version',
'my-group:my-other-artifact:version'
}

When the multi-module project updates to a new release version, run mvn install for that release and update your build.gradle as needed.

(4) Gradle 依赖 Maven:

you can “fake” including a Maven project like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
dependencies {
compile files("gradlemvn/target/classes") {
builtBy "compileMavenProject"
}

compile project(':gradledao')
testCompile group: 'junit', name: 'junit', version: '4.12'
}

task compileMavenProject(type: Exec) {
workingDir "gradlemvn/"
commandLine "/usr/bin/mvn", "clean", "compile"
}

This way Gradle will execute a Maven build (compileMavenProject) before compiling.

3. 文件依赖

1
2
3
4
5
6
apply plugin: 'java'
dependencies {
compile files('spring-core.jar', 'spring-aap.jar')
compile fileTree(dir: 'deps', include: '*.jar')
compile fileTree(dir: "${System.properties['user.home']}/libs/cargo", include: '*.jar')
}

include: '*.jar' 表示只有一级目录下面的 jar 文件才被包含,子目录下面的 jar 文件并不会被包含。

安装 Gradle

Gradle 跳过测试

1
gradle build -x test

Gradle 从外部传入参数

假设 build.gradle 脚本中有这样的语句:

1
2
3
4
5
6
7
8
project.ext {

if (project.hasProperty("buildMode")) {
mode = project.buildMode.toLowerCase()
// ...
}

}

那么,可以在外部使用 -P 选项传入参数:

1
gradle run -PbuildMode="['arg1', 'args2']"

Gradle 类似 Maven Profile 那种机制的

官方的博客 Gradle’s Support for Maven POM Profiles,示例代码:

1
2
3
4
5
if (project.hasProperty('env') && project.getProperty('env') == 'prod') {
apply from: 'gradle/production.gradle'
} else {
apply from: 'gradle/development.gradle'
}

Gradle 显示依赖树

(1) 完整依赖树

1
./gradlew app:dependencies

(2) 只显示编译时的依赖树

1
./gradlew app:dependencies --configuration compile

(3) 依赖树打印的箭头 “->” 代表什么含义

dependencies_tree_arrow

解释:4.3.5.RELEASE 是请求的版本,4.3.17 是最终选择的版本。Gradle 尝试自己来解决这些冲突,默认情况下会选择最近的版本

Gradle 排除依赖

1
2
3
compile ('us.codecraft:webmagic-core:0.6.1') {
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}

Gradle 排除子项目中的某个依赖

1
2
3
compile (project(":appsec-system-persistence")) {
exclude module: 'commons-cli'
}

Gradle 强制使用某个依赖

1
2
3
compile ('org.slf4j:slf4j-api:1.5.8') {
force = true
}

Gradle 显示 compileJava 时的真实路径

1
2
./gradlew compileJava --debug > tmp
grep 'Compiler arguments' -Rn tmp

Gradle 将 Java 工程转为 Java Web 工程

参考

推荐文章