• Gradle 笔记 2


    1 Scope

    [java]
    compileOnly
    runtimeOnly
    implementation
    testCompileOnly
    testRuntimeOnly
    testImplementation
    
    [java-library]
    api
    compileOnlyApi
    
    [war]
    providedCompile
    
    [exclude]
    implementation('org.xx:xx:xx') {
            exclude group: 'org.xx'
            exclude module: 'slf4j-api' // or
            exclude group: 'org.xx', module: 'slf4j-api'
    }
    
    [transitive]
    implementation('org.hibernate:hibernate-core:3.6.3.Final') {
            transitive(false) // no allow transitive
    }
    
    [enfore]
    implementation('org.slf4j:slf4j-api:1.4.0!!')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    2 fast-fail

    configurations.configureEach {
        resolutionStrategy {
            failOnVersionConflict() // fast-fail
            force 'animal:cat:1.0.0' // 强制依赖
        }
    }
    // 同等写法
    configurations.configureEach { Configuration config ->
        config.resolutionStrategy.failOnVersionConflict()
        config.resolutionStrategy.force('animal:cat:1.0.0')
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3 gradle command

    gradle tasks
    gradle build
    gradle run
    gradle tasks --all
    gradle dependencies
    gradle properties
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4 commandline args

    --max-workers --parallel --no-parallel -Dorg.gradle.logging.level=quiet
    -q/quiet -w/warn -i/info -d/debug -x/exclude-task --rerun-tasks # ignore up-to-date
    --continue # generate build report
    
    e.g. gradle init --type pom
    e.g. gradle myTask is equal to gradle mT
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5 dynamic invoke

    new A().printA()
    // equivalent
    def a = new A()
    invokeVirtual(a, 'printA')
    
    • 1
    • 2
    • 3
    • 4

    6 Domain-Sepcific Languages

    // equivalent to: turn(left).then(right)
    turn left then right
    
    // equivalent to: take(2.pills).of(chloroquinine).after(6.hours)
    take 2.pills of chloroquinine after 6.hours
    
    // equivalent to: paint(wall).with(red, green).and(yellow)
    paint wall with red, green and yellow
    
    // with named parameters too
    // equivalent to: check(that: margarita).tastes(good)
    check that: margarita tastes good
    
    // with closures as parameters
    // equivalent to: given({}).when({}).then({})
    given { } when { } then { }
    
    // equivalent to: select(all).unique().from(names)
    select all unique() from names
    
    // equivalent to: take(3).cookies
    // and also this: take(3).getCookies()
    take 3 cookies
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    7 Delegate & Closure

    Closure closure = {
            sayHello()
    }
    class Foo {
            void sayHello() {
                    println("hello")
            }
    }
    def foo = new Foo()
    closure.delegate = foo
    closure() // invoke
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    equivalent to internal Class

    8 Task

    task A {}
    task(map, 'B')
    tasks.create('C') {}
    tasks.register('D') {} // Lazy loading
    
    // use exist Type
    tasks.register('myClean', Delete) { 
        delete buildDir
    }
    
    task sourcesJar(type: Jar, dependsOn: classes) {
    	classifier = 'sources'
    	from sourceSets.main.allSource
    }
    
    task javadocJar(type: Jar, dependsOn: javadoc) {
    	classifier = 'javadoc'
    	from javadoc.destinationDir
    }
    
    4.times {
            tasks.register("task$it") {
                    doLast {
                            println "I'm task number $it"
                    }
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    method: tasks.findByName / getByName / findByPath / getByPath(“:project-a”)
    addRule(“description”) { taskName -> task(taskName) { doLast { print $taskName } } }

    taskName.onlyIf { !project.hasProperty(‘a’) } // return if excute
    defaultTasks ‘taskA’, ‘taskB’ // project default execute Task

    9 Daemon

    jvm start and shutdown is too heavy for system, better than keep running

    gradle connect daemon throught socket

    10 Core Object

    1. Project

    2. Task

    3. Gradle

    4. Gradle 初始化构建, 全局单例

    5. Project pom.xml 模块唯一对应

    6. Settings 项目唯一, 一般只用到 include 方法

    7. Task 前面的有向无环图基于 Task 对象

    11 Life Cycle

    Initialzation
            settings.gradle Gradle#settingsEvaluated
            build.gradle Gradle#projectsLoaded
    Configuration
            allprojects: Gradle#beforeProject and Project#beforeEvaluate
            subprojects: Gradle#beforeProject and Project#beforeEvaluate
            SubProjectA: Gradle#beforeProject and Project#beforeEvaluate
            EXECUTE build.gradle 配置段脚本
            SubProjectA: Gradle#afterProject and Project#afterEvaluate
            ALL READY:
                    Gradle#projectsEvaluated
                    Gradle#taskGraph#whenReady
    Execution
            TaskExecutionGraph#beforeTask
            EXECUTE Task Action
            TaskExecutionGraph#afterTask
            ALL EXECUTED: Gradle#buildFinish
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    12 buildscript

    plugins {
        id 'java'
        id 'org.springframework.boot' version '2.6.3'
        id 'io.spring.dependency-management' version '1.0.15.RELEASE'
    }
    
    group = 'com.xxx.xx'
    version = '1.0-SNAPSHOT'
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-web'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    }
    
    tasks.named('test') {
        // useJUnit() for junit four
        useJUnitPlatform() // for junit jupiter
    }
    
    // or
    buildscript {
        repositories {
            maven { url 'https://maven.aliyun.com/repository/public' }
        }
        dependencies {
            classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.4.1'
        }
    }
    
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    13 buildSrc 目录

    buildSrc 是 Gradle 默认的插件目录, 编译时自动识别代码, 编译成插件

    一般在 gradle init --type pom 之后会生成这个目录

    自定义插件

    buildSrc/src/main/groovy/插件代码
    buildSrc/build.gradle
    
    • 1
    • 2

    14 gradle 中的 dependencyManagement

    参考: https://docs.gradle.org/current/userguide/java_platform_plugin.html


    示例: 如果一个平台声明了org:foo:1.1的约束,并且没有其他东西带来对foo的依赖,foo将不会出现在图中。 但是,如果出现foo,那么通常的冲突解决将开始。如果依赖项引入org:foo:1.0,那么我们将选择org:foo:1.1来满足平台约束。

    1. pom 的创建
    ext {
        // ExtraPropertiesExtension ext is shorthand for project.ext, and is used to define extra properties for the project object.
        // When reading an extra property, the ext. is omitted (e.g. println project.springVersion or println springVersion).
        publishReleaseUrl = 'http://localhost:8...'
        publishSnapshotUrl = 'http://localhost:8...'
        publishUsername = 'admin'
        publishPassword = 'admin123'
    }
    
    plugins {
        id 'java-platform'
        id 'maven-publish'
    }
    
    javaPlatform {
    	// 默认为防止用户错误地引入依赖,而不是引入依赖约束,如果引入依赖会报错失败。
    	// 通过这个配置可以让Gradle允许引入依赖,当然这是可选的
        allowDependencies() // 既定义约束, 也能加入依赖
    }
    
    dependencies {
        constraints { // n. 强制; 束缚
            // 版本号管理 (要统一管理的依赖+版本)
            api 'com.java:java:1.8'
            implementation 'com.google:guava:31.1'
        }
        api platform('com.fasterxml.jackson:jackson-bom:2.9.8')
    }
    
    publishing {
    	publications {
    		myPlatform(MavenPublication) { // MyMavenJava: 发布的任务标识(会出现在面板中)
                // 指定发布成的POM文件 (GAV坐标)
                artifactId = 'poter'
                groupId = 'com.hurry'
                version = '1.0'
    
                from components.javaPlatform
    		}
    	}
    	repositories {  // 有这个才有: publish{yourdefine:myPlatform}PublicationToMavenRepository
    		maven {
                // 私服配置信息
    			if (version.endsWith('-SNAPSHOT')) {
    				url publishSnapshotUrl
    			} else {
    				url publishReleaseUrl
    			}
    			allowInsecureProtocol = true // 是否允许 http
    			credentials {
    				username publishUsername
    				password publishPassword
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    1. 发布

    在 idea gradle 面板上选择

    Tasks > publishing > publish{yourdefine}PublicationToMavenLocal
    Tasks > publishing > publish{yourdefine}PublicationToMavenRepository

    发布到Maven私服中, 此时我们能看见私服上对应的 pom 上是

    <packaging>pompackaging>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>GAVgroupId>
                ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 使用

    build.gradle

    plugins {
        id 'java-platform'
    }
    dependencies {
        implementation platform('com.hurry:poter-dependencies:1.0')
        implementation 'com.google:guava' // 此时就不用写版本号了
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    项目内

    dependencies {
        // get recommended versions from the platform project
        api platform(project(':platform'))
        // no version required
        api 'commons-httpclient:commons-httpclient'
    	api platform('com.fasterxml.jackson:jackson-bom:2.9.8')
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    15 发包添加源码

    需要插件 java-library 和 maven-publish

    • 获取系统变量 System.getenv(“系统环境变量”)
    • 获取参数: System.getProperty(“-D参数名”)
    plugins {
        id 'java-library'
        id 'maven-publish'
        id 'io.freefair.lombok' version '8.4'
    }
    
    // 注册一个名为 sourcesJar 的 Gradle 任务,使用 Jar 类型
    tasks.register('sourcesJar', Jar) {
        // 任务依赖于 classes 任务(即在执行任务之前会先执行 classes 任务, 因为需要先编译生成后的类文件
        dependsOn classes
        // 设置任务的分类器(classifier)为 'sources'. 使用分类器来区分不同类型的构建输出 (源码、文档、测试报告)
        archiveClassifier = 'sources'
        // sourceSets.main 是 Gradle 中默认的源码集合, 将 sourceSets.main 中的所有源码文件添加到 JAR 文件中
        from sourceSets.main.allSource
        // (二选一) 使用lombok插件
        from sourceSets.main.delombokTask
    }
    
    ext {
    	uname = 'uname'
    	pwd = 'pwd'
    	repoUrl = 'http:///'
    }
    version = '0.0.1-SNAPSHOT'
    
    publishing {
    	publications {
    		privatePublication(MavenPublication) { // 发布的任务标识 (会出现在gradle面板中)
    			from components.java
    			artifact sourcesJar
    		}
    	}
    	repositories {
    		maven {
    			name 'privateRepo'
    			// 私服配置信息
    			url repoUrl
    			allowInsecureProtocol = true
    			credentials {
    				username = uname
    				password = pwd
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    16 发布到中央仓库

    https://www.jetbrains.com/help/space/publish-artifacts-to-maven-central.html

    17 清除缓存

    针对同一个快照版本的 不同更新, 有时候死活拉不下来, 删除都没用时, 可以试试清除缓存

    在这里插入图片描述

    configurations.all {
        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
    }
    
    • 1
    • 2
    • 3

    这段代码将 Gradle 的缓存时间设置为0秒,强制每次都从远程仓库下载最新的快照版本

    记录的版本索引都在 maven-metadata.xml 里, 路径为
    ~/.gradle/caches/modules-2/metadata-2.**/descriptors///

    • 清除 Gradle 缓存中所有已下载的依赖项和构建中间文件,从而释放磁盘空间
    gradle cleanBuildCache
    
    • 1
    • 清除指定项目的依赖项缓存,并从远程仓库重新下载依赖项。
    gradle build --refresh-dependencies
    
    • 1

    18 排除指定依赖

    • 单个

    在 Gradle 中,可以使用 “exclude” 块来排除指定的依赖。在需要排除依赖的模块中,添加 “exclude” 块并指定要排除的依赖的组ID和artifact ID。如果需要排除多个依赖,也可以使用通配符来简化配置。例如:

    dependencies {
        implementation('com.example:example-library:1.0') {
        	// 阻止单个依赖
            exclude group: 'org.unwanted', module: 'unwanted-*'
            
            // or 阻止 "com.example:example-library:1.0" 模块所依赖的 所有其他模块 被传递到我们的项目中
            transitive = false
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ps: 如果发现没有生效, 请排查: 1. 是否有别的依赖项传递了 unwanted 依赖; 2. 是否有别的依赖项传递了 example-library 依赖;

    • 全局排除

    在 Gradle 中,可以使用 “configurations” 块来进行全局依赖排除。在 “configurations” 块中,可以定义一个名为 “all” 的配置,用于在整个项目中排除指定的依赖。例如:

    configurations {
        all {
            exclude group: 'org.unwanted', module: 'unwanted-library'
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ps: 这种方法可能会影响到整个项目的构建过程,因此应该谨慎使用。如果只需要在特定模块中排除依赖,应该尽量避免在全局配置中进行排除。

  • 相关阅读:
    linux C++注册程序退出信号处理的代码
    大数据培训FileInputFormat实现类
    后仿真中的 《specify/endspecify block》之(5)使用specify进行时序仿真
    【数据结构】——单链表
    【第100题】JAVA高级技术-网络编程19(简易聊天室14:聊天室客户端)
    基于STM32的电子时钟(论文+源码)
    vscode安装和配置c++/c环境
    Java算术运算符简介说明
    Kotlin 协程 知识点
    比Requests强100倍的神器python工具!
  • 原文地址:https://blog.csdn.net/howeres/article/details/127874606