Gradle之基础(一)

版本

  1. gradle-4.8.1

安装

  1. 安装JDK

  2. 配置GRADLE_HOME,配置PATH

    export GRADE_HOME=/Volumes/P/develope/gradle-4.8.1
    export PATH=$PATH:$GRADE_HOME/bin
    
  3. 验证安装

           
           $ gradle –v
           
           ------------------------------------------------------------
           Gradle 4.8.1
           ------------------------------------------------------------
           
           Build time:   2018-06-21 07:53:06 UTC
           Revision:     0abdea078047b12df42e7750ccba34d69b516a22
           
           Groovy:       2.4.12
           Ant:          Apache Ant(TM) version 1.9.11 compiled on March 23 2018
           JVM:          1.8.0_45 (Oracle Corporation 25.45-b02)
           OS:           Mac OS X 10.14.3 x86_64
    
    

配置

修改本地缓存目录

  1. 默认情况下本地仓库的位置在系统的用户目录.gradle文件夹下

  2. 方式一,修改$GRADE_HOME/bin/gradle

      在gradle的安装目录,编辑bin文件夹下的gradle文件,然后找到如下语句:
    Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
    DEFAULT_JVM_OPTS=""
    GRADLE_OPTS=-Dgradle.user.home=/Volumes/P/develope/GradleRepository
    
  3. 方式二,修改项目的gradle.properties文件

    gradle.user.home=/Volumes/P/develope/GradleRepository
    缺点:每个项目都要这么加一次.
    
  4. 方式三,设置GRADLE_USER_HOME环境变量

    export GRADLE_USER_HOME=/Volumes/P/develope/GradleRepository
    
  5. 方式四,通过参数修改

    gradle -g /Volumes/P/develope/GradleRepository  build
    

配置本地Maven仓库

  1. 配置

    repositories {
        mavenLocal()
    }
    
  2. Gradle使用与Maven相同的策略去定位本地Maven缓存的位置。如果在settings.xml中定义了本地Maven仓库的地址,则使用该地址。在USER_HOME/.m2下的settings.xml文件中的配置会覆盖存放在M2_HOME/conf下的settings.xml文件中的配置。如果没有settings.xml配置文件,Gradle会使用默认的USER_HOME/.m2/repository地址。

    mavenLocal()表示会从本地获取资源,获取资源的顺序为
    
     1. %USER_HOME%/.m2/settings.xml中指定的路径 
    
     2. %M2_HOME%/conf/settings.xml中指定的路径 
    
     3. %USER_HOME%/.m2/repository
    
  3. 这里发现一个BUG,按照官方文档说,如果系统用户文件夹下的.m2中不存在settings.xml文件会自动去找%M2_HOME%的settings.xml文件,实际却不会,然后直接指向了%USER_HOME%/.m2/repository。建议自定义maven本地库的,把%M2_HOME%的settings.xml文件COPY一份到%USER_HOME%/.m2目录下即可。

命令行选项

常用命令

  1. 帮助

    gradle --help
    
  2. 查看所有可执行的tasks

    gradle tasks
    
  3. Maven与Gradle互转

    1. maven转gradle
    gradle init -–type pom
    
    2. gradle转maven
    
    apply plugin: 'maven'
    gradle install
    将会在当前Module项目的build目录下的poms文件夹下生成pom-default.xml,将其拷贝到项目的根目录下即可
    
  4. 强制刷新依赖

    $ gradle build --refresh-dependencies 
    
  5. 离线构建

    $ gradle build --offline
    
  6. 查看项目层次关系

    $ gradle project
    
  7. 查看任务

    $ gradle -q tasks
    
  8. 跳过测试构建

    gradle build -x test 
    
  9. 禁用构建缓存

    1. ~/.gradle/gradle.properties 或者项目中的gradle.properties添加
    org.gradle.caching=false
    
    2. 删除缓存
    rm -rf $HOME/.gradle/caches/
    
    3. 删除wrapper
    rm -rf $HOME/.gradle/wrapper/
    
    
  10. 停止后台线程,为了确保gradle配置生效,建议使用停止已有的daemon

    gradle --stop
    
  11. 命令行选项

    1. –?,h,--help:打印出所有可用的命令行选项包含描述信息
    2. –b gradle构建脚本的默认约定是build.gradle,-b可以执行一个特定的构建脚本,比如gradle –b test.gradle
    3. –-offline:通常,构建中声明的依赖必须在离线仓库中存在才可用。如果这些依赖在本地缓存中没有,那么运行在一个没有网络连接环境中的构建都会失败。使用这个选项可以让你以离线模式运行构建,仅仅在本地缓存中检查依赖是否存在
    4. -i,--info:在默认设置中,gradle不会提供大量的输出信息。-i表示日志是info
    5. –s 在抛出异常时会打印堆栈信息(--stracktrace)
    6. –q,--quiet 减少构建出错时打印出来的错误日志信息
    7. -m, --dry-run 模拟任务执行过程并将过程打印出来,并非真正执行,只是为了让你知道会执行哪些步骤.
    8. --max-workers  指定采用几个CPU核心执行构建
    

日志

  1. 如果需要调试信息,可以使用内置的logger更灵活地控制输出不同级别的日志,本质上是调用Project的getLogger()方法获取的Logger对象
logger.quiet()
logger.error()
logger.warn()
logger.info()
logger.debug()
  1. 日志参数

    命令参数级别描述
    没有日志选项LIFECYCLE 及更高
    -q or –quietQUIET 及更高
    -i or –infoINFO 及更高
    -d or –debugDEBUG 及更高
    -s or –stacktrace打印关键堆栈信息
    -S or–full-stacktrace打印全栈信息

查看依赖报告

  1. 查看依赖报告

    $ gradle  dependencies > dep.log
    
    
    带(*)依赖意味着被不同的库重复依赖了若干次,(*)表示该依赖被忽略掉了
    而->则表示其它的定级依赖的传递依赖中存在更高版本的依赖,该版本将会使用->后面的版本来替代。
    |    +--- org.mybatis:mybatis-spring:1.1.0
    |    |    |    +--- org.mybatis:mybatis:3.1.0 -> 3.3.1
    |    |    |    +--- org.springframework:spring-core:3.1.1.RELEASE -> 4.2.5.RELEASE
    |    |    |    |    \--- commons-logging:commons-logging:1.2
    |    |    |    +--- org.springframework:spring-tx:3.1.1.RELEASE -> 4.1.3.RELEASE
    |    |    |    |    +--- org.springframework:spring-beans:4.1.3.RELEASE -> 4.2.5.RELEASE
    |    |    |    |    |    \--- org.springframework:spring-core:4.2.5.RELEASE (*)
    |    |    |    |    \--- org.springframework:spring-core:4.1.3.RELEASE -> 4.2.5.RELEASE (*)
    |    |    |    +--- org.springframework:spring-jdbc:3.1.1.RELEASE
    |    |    |    |    +--- org.springframework:spring-beans:3.1.1.RELEASE -> 4.2.5.RELEASE (*)
    |    |    |    |    +--- org.springframework:spring-core:3.1.1.RELEASE -> 4.2.5.RELEASE (*)
    |    |    |    |    \--- org.springframework:spring-tx:3.1.1.RELEASE -> 4.1.3.RELEASE (*)
    |    |    |    \--- org.springframework:spring-context:3.1.1.RELEASE -> 4.2.5.RELEASE
    |    |    |         +--- org.springframework:spring-aop:4.2.5.RELEASE
    |    |    |         |    +--- aopalliance:aopalliance:1.0
    |    |    |         |    +--- org.springframework:spring-beans:4.2.5.RELEASE (*)
    |    |    |         |    \--- org.springframework:spring-core:4.2.5.RELEASE (*)
    |    |    |         +--- org.springframework:spring-beans:4.2.5.RELEASE (*)
    |    |    |         +--- org.springframework:spring-core:4.2.5.RELEASE (*)
    |    |    |         \--- org.springframework:spring-expression:4.2.5.RELEASE
    |    |    |              \--- org.springframework:spring-core:4.2.5.RELEASE (*)
    
    
    

init.gradle

  1. 作用

    • 建立内部的配置,如定义公司内部的仓库地址
    • 配置一些全局属性,比如配置持续集成服务器的地址等配置
    • 提供构建所需要的用户的个人信息,如仓库或数据库的用户名和密码
    • 用来定义开发者机器的环境,比如定义jdk安装位置
    • 以用来注册一些监听器。比如监听Gradle事件的发生,做一些额外的操作,例如需要对某个项目构建前和构建后做一些操作,又例如对项目的依赖做检测,检测是否含有snapshot包,在release构建中一般来说是禁止依赖snapshot包的,所以这时候就可以扔出一个异常
    • 重定向日志。我们可以将gradle默认的日志进行重定向,甚至可以不输出默认日志,自定义如何输出gradle产生的日志信息。
  2. 加载顺序:Gradle会依次对一些目录进行检测,按照优先级加载这些目录下的文件,如果一个目录下有多个文件被找到,则按照英文字母的顺序依次加载。加载优先级如下

    • 通过--I 或者 --init-script 参数在构建开始时指定路径

      gradle --init-script init.gradle clean
      gradle --I init.gradle assembleDebug
      
    • 加载$USER_HOME/.gradle/init.gradle文件

    • 加载$USER_HOME/.gradle/init.d/目录下的以.gradle结尾的文件

    • 加载$GRADLE_HOME/init.d/目录下的以.gradle结尾的文件

  3. Init.gradle

    //gradle的可执行目录
    gradle.println "gradleHomeDir:${gradle.gradleHomeDir}"
    //gradle的用户目录,用于缓存一些下载好的资源,编译好的构建脚本等
    gradle.println "gradleUserHomeDir:${gradle.gradleUserHomeDir}"
    //gradle的版本号
    gradle.println "gradleVersion:${gradle.gradleVersion}"
    //gralde当前构建的启动参数
    gradle.println "startParameter:${gradle.startParameter}"
    
  4. 定义第三方库

    initscript {
        //定义init.gradle所需要的仓库地址
        repositories {
            jcenter()
            mavenCentral()
            mavenLocal()
        }
        //加入依赖
        dependencies {
            classpath 'org.apache.commons:commons-math:2.0'
        }
    }
    
  5. 定义全局的配置信息

    //init.gralde可以配置一些全局的配置,比如仓库的地址等
    import java.util.concurrent.TimeUnit
    allprojects { Project project ->
        buildscript {
            repositories {
                maven {
                    url "htttp://url/to/maven"
                }
                jcenter()
                mavenCentral()
                mavenLocal()
            }
        }
        repositories {
            maven {
                url "htttp://url/to/maven"
            }
            jcenter()
            mavenCentral()
            mavenLocal()
        }
        configurations.all {
            resolutionStrategy {
                // cache dynamic versions for 10 minutes
                cacheDynamicVersionsFor 10 * 60, TimeUnit.SECONDS
                // don't cache changing modules at all
                cacheChangingModulesFor 0, TimeUnit.SECONDS
            }
        }
    }
    

build配置

wrapper

  1. Gradle包装器是Gradle的核心特性,能够让机器在没有安装Gradle运行时的情况下运行Gradle构建。它也让构建脚本运行在一个指定的Gradle版本上。它是通过自动从中心仓库下载Gradle运行时,解压和使用来实现的。最终的目标是创造一个独立于系统、系统配置和Gradle版本的可靠和可重复的构建

  2. 配置wrapper,下载目录**$USER_HOME/.gradle/warpper/dists**

    task wrapper(type: Wrapper) {
        description = 'Generates gradlew[.bat] scripts'
        gradleVersion = '4.8.1'
        distributionUrl = "http://services.gradle.org/distributions/gradle-4.8.1-bin.zip"
        //distributionUrl = "file:///Volumes/P/develope/gradle-${gradleVersion}-bin.zip"
    }
    
  3. 执行任务生成包装器文件(只需要在项目中运行一次gradle wrapper)

    1. 执行
    $ gradle wrapper
    2. 更新版本,也可以修改wrapper任务
    $ ./gradlew wrapper --gradle-version=4.8.1
    

配置仓库地址

  1. 配置仓库地址

        repositories {
            mavenLocal()
            maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
            mavenCentral()
        }
    
    

远程仓库检查

  1. 快照版本更新,gradle为了加快构建的速度,对jar包默认会缓存24小时,缓存之后就不在请求远程仓库了。为了及时更新快照版本,需要设置更新策略。参见https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html

    configurations.all {
        //每隔24小时检查远程依赖是否存在更新
        //resolutionStrategy.cacheChangingModulesFor 24, 'hours'
        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
        //每隔10分钟..
        //resolutionStrategy.cacheChangingModulesFor 10, 'minutes'
        // 采用动态版本声明的依赖缓存10分钟
        resolutionStrategy.cacheDynamicVersionsFor 10*60, 'seconds'
    }
    
    
    dependencies {
        // 添加changing: true
        compile group: "group", name: "module", version: "1.1-SNAPSHOT", changing: true
        //简写方式
        //compile('group:module:1.1-SNAPSHOT') { changing = true }
    }
    

引入其他的gradle文件

  1. build.gradle中使用如下代码引入example.gradle和taskTest.gradle两个脚本文件

    apply (from:'example.gradle')
    apply from: 'taskTest.gradle'
    或者使用绝对路径
    apply from: rootProject.getRootDir().getAbsolutePath() + "/example.gradle"
    

自定义属性

  1. 在gradle中添加额外的属性时,使用【ext.属性名】

    ext.projectVersion='1.0.0-SNAPSHOT'
    
    或者通过闭包的方式,闭包的方式可以指定多个属性
    ext {
        projectVersion = '1.0.0-SNAPSHOT'
        group = 'cn.jannal.test'
        
    }
    
  2. 在外部gradle文件中中定义,比如定义ext.gradle文件

    ext {
        projectVersion = '1.0.0-SNAPSHOT'
        group = 'cn.jannal.test'
        
    }
    //引入外部配置
    apply from: rootProject.getRootDir().getAbsolutePath() + "/ext.gradle"
    
  3. 在使用属性的时候不需要加ext前缀,直接使用即可

  4. 查看所有属性

    $ gradle properties
    
  5. -D使用Gradle通过-D也可以传递参数给JVM,-Dorg.gradle.project.prop=somevalue。也可以通过Gradle特有的参数-P来传值,格式如-Pprop=somevalue,还可以通过gradle.properties配置文件来传递,配置文件还可以设置系统参数,系统参数是以systemProp.为前缀,格式systemProp.prop=somevalue,通过System.properties['prop']来获取

    1. 通过配置项传递
    task showProp{
        doLast{
            if(project.hasProperty('username')){
                println username
            }
        }
    }
    $ gradle -q showProp -Dorg.gradle.project.username=jannal
    $ gradle -q showProp -Pusername=jannal  
    
    
    2. 在 gradle.properties中配置
    
    username=jannal
    
    $  gradle -q showProp  
    
    3. 获取系统参数
    
    systemProp.SystemUsername=admin
    
    task showProp2{
        doLast{
            println System.properties['SystemUsername']
        }
    }
    $ gradle -q showProp2
    
    

简单案例

  1. 新建gradle-core项目并编写build.gradle
    group 'com.jannal.gradle'
    version '1.0-SNAPSHOT'
    
    //使用groovy插件
    apply plugin: 'groovy'
    /**
     * 使用java插件,java插件引入源代码的位置约定src/main/java目录
     * java插件提供一个任务是build(编译、打包、测试),如果一个任务被标记为
     * UP-TO-DATE表示这个任务被跳过
     */
    apply plugin: 'java'
    
    sourceCompatibility = 1.8
    
    //定义仓库
    repositories {
        mavenCentral()
    }
    //定义依赖
    dependencies {
        compile 'org.codehaus.groovy:groovy-all:2.3.11'
        testCompile group: 'junit', name: 'junit', version: '4.12'
    }
    
    
    jar{
        manifest{
            //将Main-Class头添加到jar文件中
            attributes 'Main-Class':'com.jannal.gradle.MainRun'
        }
    }
  1. 构建步骤
$ gradle build
$ java -jar ./build/libs/gradle-core-1.0-SNAPSHOT.jar 

多项目配置

  1. settings.gradle

    rootProject.name = 'abc'
    include 'abc-api'
    include 'abc-test'
    include 'abc-core'
    include 'abc-common'
    
    或者
    rootProject.name = 'abc'
    include 'abc-api','abc-test','abc-core','abc-common'
    
  2. 多项目模块依赖

    1. abc-api的build.gradle配置
    
    dependencies {
        compile project(':abc-common')
        compile project(':abc-core')
    }    
    

gradle.properties

  1. gradle命令运行时会默认读取$GRADLE_HOME和当前项目根目录下的gradle.properties文件,因此在gradle脚本中可以直接使用其中的内容,例如:

        //读取gradle.properties文件中存在osName属性,则直接使用
        if(hasProperty("osName")){
            println(osName)
        }
        //hasProperty方法为Project对象的成员,用于判断当前属性是否存在。
    
    
  2. gradle.properties中的内容不需要显示调用就可以直接在build.gradle中进行使用. 在该文件中定义需要的属性。这些属性在Gradle构建Gradle领域对象(即project对象实例)时会被自动加到project对象实例中作为其属性被直接调用。

  3. gradle.properties 文件也是含有两个,但是却是一个是全局,一个是项目的. 全局文件存在于$USER_HOME\.gradle文件夹中. 该文件有可能没有,需要自己创建,创建后所有项目都将具有访问权限,在该文件中一般保存的是项目的一些变量,也可以覆盖默认的变量

    # 开启后台运行,Gradle3.0后默认是开启daemon的
    org.gradle.daemon=true
    #jvm参数
    org.gradle.jvmargs=-Xms2G -Xmx2G -Xss256k -Djava.awt.headless=true -Dfile.encoding=UTF-8 -XX:MetaspaceSize=128m  -XX:SurvivorRatio=6  -XX:NewRatio=4   -XX:MaxTenuringThreshold=12  -XX:PretenureSizeThreshold=5242880  -XX:+UseConcMarkSweepGC  -XX:CMSInitiatingOccupancyFraction=70  -XX:+UseCMSInitiatingOccupancyOnly  -XX:+CMSClassUnloadingEnabled  -XX:+DoEscapeAnalysis  -XX:+EliminateAllocations
    # 并行构建
    org.gradle.parallel=true
    # 孵化模式
    org.gradle.configureondemand=true
    # 开启缓存
    org.gradle.caching=false
    
  4. 守护进程:每次初始化一个构建jvm都要启动一次,gradle的依赖要载入到类加载器中,还要建立项目对象模型。这个过程需要好几秒。守护进程以后台进程方式运行gradle,一旦启动,gradle命令就会在后续的构建中重用之前创建的守护进程,以避免启动带来的开销。

    1. 方式一: 在运行gradle时加上--daemon选项可启动守护进程。
    --no-daemon 在构建时不使用守护进程。
    --stop 停止守护进程 。 
    ps -ef|grep gradle 查看守护进程
    
    2. 方式二: 在gradle.properties中加入
    
    org.gradle.daemon=true
    

依赖管理

  1. 声明依赖

    // 基本格式
    configurationName dependencyNotation1, dependencyNotation2, ...
    
    // 高级格式
    configurationName(dependencyNotation){
    	configStatement1
    	configStatement2
    }
    
    • configurationName: 类似compile、testCompile等
  1. 依赖管理

    compileOnlygradle2.12之后版本新添加的,2.12版本时期曾短暂的叫provided,后续版本已经改成了compileOnly,由java插件提供,适用于编译期需要而不需要打包的情况
    providedCompilewar插件提供的范围类型:与compile作用类似,但不会被添加到最终的war包中这是由于编译、测试阶段代码需要依赖此类jar包,而运行阶段容器已经提供了相应的支持,所以无需将这些文件打入到war包中了;例如Servlet API就是一个很明显的例子.
    compile编译范围依赖在所有的classpath中可用,同时它们也会被打包。在gradle3.0后其实compile就是过时的了,引出了api和implementation
    apiapi其实和compile没区别,依赖项传递到其他模块
    implementation模块在编译的时候不需要把依赖项泄露给其他模块,即依赖不会传递
    providedRuntime同proiveCompile类似。providedCompile 只有war插件才可以使用
    runtimeruntime依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。
    testCompile测试期编译需要的附加依赖
    testRuntime测试运行期需要
    archives-
    default配置默认依赖范围
  2. 依赖项目中的module

    dependencies {
    	//项目依赖,:是基于根项目的相对路径
    	compile project(':abc-core') 
    }
    
    
  3. 依赖本地jar

    dependencies {
      //依赖一个jar
      compile files('libs/sdk-1.1.jar') 
      //依赖多个jar
      compile files('hibernate.jar', 'libs/spring.jar') 
      //读取libs文件夹下全部的文件作为项目依赖
    	compile fileTree('libs')
    	//根据指定基准目录(包含,排除条件加载依赖)
    	compile fileTree(dir:'libs',include:'spring*.jar',exclude:'hibernate*.jar')
    }  
    
  4. 外部依赖

    dependencies {
      // 采用map方式传入单个
      compile group: 'commons-lang', name: 'commons-lang', version: '2.6'
      // 采用简写方式声明
      compile 'org.projectlombok:lombok:1.16.10' 
      // 采用map方式传入多个,一般用于聚合一些库,这些库依赖需要一起依赖,删除需要一起删除
      compile(
          [group: 'org.springframework', name: 'spring-core', version: '2.5'],
          [group: 'org.springframework', name: 'spring-aop', version: '2.5']
      )
      // 采用简写方式传入多个 
      compile 'org.springframework:spring-core:2.5',
              'org.springframework:spring-aop:2.5'
    
    }
    
  5. 内置依赖,跟随Gradle发行包或者基于Gradle API的一些依赖,通常在插件开发时使用

    dependencies {
       // 加载Gradle自带的groovy作为依赖
       compile localGroovy()
       // 使用Gradle API作为依赖
       compile gradleApi()
       /使用 Gradle test-kit API 作为依赖
       testCompile gradleTestKit()
     }
    

配置管理

  1. Gradle将对依赖进行分组,比如编译Java时使用的是这组依赖,运行Java时又可以使用另一组依赖。每一组依赖称为一个Configuration,在声明依赖时,我们实际上是在设置不同的Configuration

  2. 将依赖称为Configuration并不是一个好的名字,可以叫做dependencies group,类似Maven中的scope

  3. 打印所有的依赖组(Configuration)

    task printAllConfigurations {
        doLast {
            def allConfigurations = project.configurations.getAll()
            println "项目中所有依赖组:${allConfigurations.size()}"
            println "获取compile依赖组的名称${project.configurations.compile.getClass()}"
            allConfigurations.each { c ->
                println c
            }
        }
    }
    项目中所有依赖组:20
    获取compile依赖组的名称class org.gradle.api.internal.artifacts.configurations.DefaultConfiguration_Decorated
    configuration ':annotationProcessor'
    configuration ':apiElements'
    configuration ':archives'
    configuration ':compile'
    configuration ':compileClasspath'
    configuration ':compileOnly'
    configuration ':default'
    configuration ':implementation'
    configuration ':runtime'
    configuration ':runtimeClasspath'
    configuration ':runtimeElements'
    configuration ':runtimeOnly'
    configuration ':testAnnotationProcessor'
    configuration ':testCompile'
    configuration ':testCompileClasspath'
    configuration ':testCompileOnly'
    configuration ':testImplementation'
    configuration ':testRuntime'
    configuration ':testRuntimeClasspath'
    configuration ':testRuntimeOnly'
    
  4. 定义一个依赖组

    1. 定义依赖组
    configurations {
       jannalDependency
    }
    
    2. 加入依赖
    dependencies {
       jannalDependency 'org.apache.commons:commons-lang3:3.0'
    }
    
    3. 定义任务
    task showMyDependency << {
       println configurations.myDependency.asPath
    }
    
    4. 执行任务
    
    $ gradle -q showMyDependency
    
    /Volumes/P/develope/GradleRepository/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.0/8873bd0bb5cb9ee37f1b04578eb7e26fcdd44cb0/commons-lang3-3.0.jar
    
    
    
  5. 继承已有的依赖组

    configurations {
        smokeTest.extendsFrom testImplementation
    }
    
    dependencies {
        testImplementation 'junit:junit:4.12'
        smokeTest 'org.apache.httpcomponents:httpclient:4.5.5'
    }
    
  6. 默认插件的依赖组,java Plugin会自动定义compile和testCompile,分别用于编译Java源文件和编译Java测试源文件。另外,java Plugin还定义了runtime和testRuntime这两个Configuration,分别用于在程序运行和测试运行时加入所配置的依赖。

依赖传递

  1. 传递性依赖,可以通过transitive = false的方式来关闭,也可以采用添加**@jar**的方式忽略该依赖的所有传递性依赖。
dependencies {
    // 让ptj.tiger作为druid的传递性依赖
    compile module("com.alibaba:druid:1.0.26") {
        dependency("cn.pkaq:ptj.tiger:+")
    }

    runtime module("org.codehaus.groovy:groovy:2.4.7") {
        // 停用groovy依赖的commons-cli库的依赖传递
        dependency("commons-cli:commons-cli:1.0") {
            transitive = false
        }
        //让groovy依赖的ant模块的依赖ant-launcher停用传递性依赖并依赖ant-junit..........
        module(group: 'org.apache.ant', name: 'ant', version: '1.9.6') {
            dependencies "org.apache.ant:ant-launcher:1.9.6@jar",
                         "org.apache.ant:ant-junit:1.9.6"
        }
    }
 }
  1. 全局关闭依赖传递

    configurations.all {
       transitive = false
    }
    
  2. 排除部分依赖exclude,以下场景需要排除依赖

    • 依赖冲突时,如果有两个依赖引用了相同jar包的不同版本时,默认情况下gradle会采用最新版本的jar包,此时可以通过排除选项来排除。
    • 运行期无需此模块的
    • 无法正常获取到此传递依赖,远程仓库都不存在的
    • 版权原因需要排除的
    • 其他原因。
  3. 全局排除

    configurations {
        //编译期排除commons模块
        compile.exclude module: 'commons'
        //在整个构建过程中排除pkaq.tiger:share
        all*.exclude group: 'pkaq.tiger', module: 'share'
    }
    
  4. 局部排除

    dependencies {
        compile("pkaq.tiger:web:1.0") {
            exclude module: 'share'
        }       
    }
    
  5. 全局强制使用当前版本

    configurations.all {
       resolutionStrategy {
           force 'org.hamcrest:hamcrest-core:1.3'
       }
    }
    
  6. 局部强制使用当前版本

    compile('org.hibernate:hibernate:3.1') {
        force = true
    }
    
  7. 综合示例

    compile('org.hibernate:hibernate:3.1') {
       // 冲突时优先使用该版本
       force = true
       // 依据构建名称排除
       exclude module: 'cglib' 
       // 依据组织名称排除
       exclude group: 'org.jmock' 
       // 依据组织名称+构件名称排除
       exclude group: 'org.unwanted', module: 'iAmBuggy' 
       // 为本依赖关闭依赖传递特性
       transitive = false
    }
    
  8. gradle应对版本冲突的策略

    • 选择最新的依赖版本
    • gradle不会自动通知你的项目遇到了版本冲突问题
  9. 可以更改默认策略,当遇到版本冲突时构建失败

    configurations.all {
        resolutionStrategy {
            // fail eagerly on version conflict (includes transitive dependencies)
            // e.g. multiple different versions of the same dependency (group and name are equal)
            failOnVersionConflict()
        }
    
    }
    

遇到的问题

  1. 命令行可以构建,但是idea不能构建

    1. 在build.gradle里添加 apply plugin: "idea"
    2. 然后在命令行里执行 gradle idea
    3. 重启idea
    
  2. 遇到Java home is different异常

    Failed to complete Gradle execution.
    Caused by: org.gradle.launcher.daemon.client.DaemonConnectionException: The newly created daemon process has a different context than expected.
    It won't be possible to reconnect to this daemon. Context mismatch: 
    Java home is different.
    Wanted: DefaultDaemonContext[uid=null,javaHome=/Applications/IntelliJ IDEA.app/Contents/jdk/Contents/Home,daemonRegistryDir=/Users/jannal/.gradle/daemon,pid=7884,idleTimeout=null,daemonOpts=-XX:+HeapDumpOnOutOfMemoryError,-Xmx1024m,-Dfile.encoding=UTF-8,-Duser.country=CN,-Duser.language=zh,-Duser.variant]
    Actual: DefaultDaemonContext[uid=fea6af15-7e98-4835-ab4f-404fc7878c1a,javaHome=/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home,daemonRegistryDir=/Users/jannal/.gradle/daemon,pid=9834,idleTimeout=10800000,daemonOpts=-XX:+HeapDumpOnOutOfMemoryError,-Xmx1024m,-Dfile.encoding=UTF-8,-Duser.country=CN,-Duser.language=zh,-Duser.variant]
    
    解决方法:
    gradle.properties (放在项目的根目录或者%USER_HOME%/.gradle目录下)中加入org.gradle.java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home
    
    
  3. 覆盖默认springboot中声明的jar版本号

     ext['elasticsearch.version']='6.3.2'
    
    
  4. 出现提示’“Task :xxx:compileJava FAILED 1 个错误”’

         查看是否有类似的配置
        tasks.withType(JavaCompile) {
            options.compilerArgs += ["-Werror"]
        }
    
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值