为啥即使源代码没有变化,Gradle 的“构建”任务也不是最新的?

Posted

技术标签:

【中文标题】为啥即使源代码没有变化,Gradle 的“构建”任务也不是最新的?【英文标题】:Why Gradle 'build' task is not up-to-date even there is no change in the source code?为什么即使源代码没有变化,Gradle 的“构建”任务也不是最新的? 【发布时间】:2016-10-28 10:34:29 【问题描述】:

我为 Spring 应用程序创建了一个 Gradle 项目。我的 build.gradle 如下:

buildscript 
    ext 
        springBootVersion = '1.3.5.RELEASE'
    
    repositories 
        mavenCentral()
        jcenter()
    
    dependencies 
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion")
        classpath('org.asciidoctor:asciidoctor-gradle-plugin:1.5.3')
    


apply plugin: 'java'
apply plugin: 'spring-boot'

jar 
    baseName = 'edge'
    version = '0.0.1-SNAPSHOT'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories 
    mavenCentral()


bootRepackage 
    excludeDevtools = true


dependencies 
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-actuator-docs')
    compile('org.springframework.boot:spring-boot-starter-aop')
    compile('org.springframework.cloud:spring-cloud-starter-config')
    compile('org.springframework.cloud:spring-cloud-starter-eureka')
    compile('org.springframework.cloud:spring-cloud-starter-hystrix')
    compile('org.springframework.cloud:spring-cloud-starter-hystrix-dashboard')
    compile('org.springframework.cloud:spring-cloud-starter-ribbon')
    compile('org.springframework.cloud:spring-cloud-starter-zuul')
    compile('org.springframework.boot:spring-boot-starter-hateoas')
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-redis')
    compile('org.projectlombok:lombok:1.16.6')
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.session:spring-session')
    compile('org.springframework.boot:spring-boot-starter-web') 
        exclude module: 'spring-boot-starter-tomcat'
    
    compile('org.springframework.boot:spring-boot-starter-undertow')
    compile('org.springframework.boot:spring-boot-starter-websocket')
    compile('com.h2database:h2')
    compile('org.springframework.boot:spring-boot-devtools')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.springframework.restdocs:spring-restdocs-mockmvc')


dependencyManagement 
    imports 
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:Brixton.RELEASE"
    


eclipse 
    classpath 
         containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
         containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
    

然后每次我运行gradle build 而不对源代码进行任何更改时,总是执行几个任务,而我认为它们应该是最新的:

➜  octopus git:(master) ✗
➜  octopus git:(master) ✗ gradle :edge:build
:edge:compileJava UP-TO-DATE
:edge:processResources UP-TO-DATE
:edge:classes UP-TO-DATE
:edge:findMainClass
:edge:jar
:edge:bootRepackage
:edge:assemble
:edge:compileTestJava UP-TO-DATE
:edge:processTestResources UP-TO-DATE
:edge:testClasses UP-TO-DATE
:edge:test UP-TO-DATE
:edge:check UP-TO-DATE
:edge:build

BUILD SUCCESSFUL

Total time: 6.773 secs

This build could be faster, please consider using the Gradle Daemon: https://docs.gradle.org/2.13/userguide/gradle_daemon.html
➜  octopus git:(master) ✗ md5 edge/build/libs/edge-0.0.1-SNAPSHOT.jar
MD5 (edge/build/libs/edge-0.0.1-SNAPSHOT.jar) = d0ff71c362d089559bbc627e78e2247a
➜  octopus git:(master) ✗ gradle :edge:build
:edge:compileJava UP-TO-DATE
:edge:processResources UP-TO-DATE
:edge:classes UP-TO-DATE
:edge:findMainClass
:edge:jar
:edge:bootRepackage
:edge:assemble
:edge:compileTestJava UP-TO-DATE
:edge:processTestResources UP-TO-DATE
:edge:testClasses UP-TO-DATE
:edge:test UP-TO-DATE
:edge:check UP-TO-DATE
:edge:build

BUILD SUCCESSFUL

Total time: 6.579 secs

This build could be faster, please consider using the Gradle Daemon: https://docs.gradle.org/2.13/userguide/gradle_daemon.html
➜  octopus git:(master) ✗ md5 edge/build/libs/edge-0.0.1-SNAPSHOT.jar
MD5 (edge/build/libs/edge-0.0.1-SNAPSHOT.jar) = d1c3fc5c9d0c00e0130c8c65f23b6466
➜  octopus git:(master) ✗

如您所见,任务 'findMainClass'、'jar'、'bootRepackage'、'assemble' 和 'build' 被认为是非最新的并且总是被执行。而且每次生成的jar文件都不一样,因为它们有不同的MD5摘要。

那么,为什么 Gradle 会这样呢?如何使它们全部更新并加快构建过程?

【问题讨论】:

【参考方案1】:

默认情况下,Spring Boot 的 bootRepackage 任务会覆盖由 jar 任务创建的 jar。这意味着jar 任务始终被视为已过期。您可以通过使用分类器配置 bootRepackage 来避免这种情况,以便将重新打包的 fat jar 写入单独的位置。例如:

bootRepackage  
    classifier = 'exec'

您可能还对this issue 感兴趣,它描述了我们希望对 Boot 的 Gradle 插件进行的一些改进。

【讨论】:

谢谢。真正困扰我的是,我使用com.bmuschko:gradle-docker-plugin 与 docker 集成,它的任务是构建包含可执行 jar 的 docker 映像。每次我在不更改源代码的情况下执行gradle buildDockerImage,它总是会构建docker镜像,这是一项耗时的任务。

以上是关于为啥即使源代码没有变化,Gradle 的“构建”任务也不是最新的?的主要内容,如果未能解决你的问题,请参考以下文章

即使没有任何更改,Android 多模块 Gradle 构建也很慢

Gradle Wrapper

为啥我的 Gradle 构建会因退出代码 137 而死?

为啥即使我没有将 vuex 状态绑定到任何 html 输入元素,我的 vuex 状态也会在更改组件级别状态时发生变化?

为啥即使没有 SVN 更改,Jenkins 也会触发 IVY 构建?

为啥我在构建项目时出现 Flutter gradle 错误?