Skip to content

ShadowJar task has build cache miss on consecutive builds #1991

@ribafish

Description

@ribafish

Expected and Results

Expected: Running clean shadowJar twice in a row with local build cache enabled should result in the shadowJar task being FROM-CACHE on the second run.

Actual: The shadowJar task has a cache miss and re-executes on the second run, even though no inputs have changed.

Related environment and versions

  • Shadow plugin: 9.3.2 (also verified on 9.4.0 release notes — no caching fix mentioned)
  • Gradle: 9.4.1
  • Observed in: micrometer-metrics/micrometer implementations/micrometer-registry-statsd/build.gradle

Reproduction steps

This was observed in the micrometer project which has the following shadowJar configuration:

shadowJar {
    duplicatesStrategy = DuplicatesStrategy.INCLUDE
    failOnDuplicateEntries = true
    configurations.set([project.configurations.compileClasspath])
    archiveClassifier.set('')
    dependencies {
        include(dependency('io.projectreactor:.*'))
        include(dependency('io.projectreactor.netty:.*'))
        include(dependency('org.reactivestreams:reactive-streams:.*'))
        include(dependency('io.netty:.*'))
        exclude("META-INF/maven/**")
        exclude("META-INF/io.netty.versions.properties")
    }
    relocate 'reactor', 'io.micrometer.shaded.reactor'
    relocate 'org.reactivestreams', 'io.micrometer.shaded.org.reactorstreams'
    relocate 'io.netty', 'io.micrometer.shaded.io.netty'
    relocate 'META-INF/native/libnetty', 'META-INF/native/libio_micrometer_shaded_netty'
    metaInf {
        from "$rootDir/LICENSE"
        from "$rootDir/NOTICE"
    }
    mergeServiceFiles()
}

Steps to reproduce:

  1. Clone micrometer: git clone https://github.com/micrometer-metrics/micrometer
  2. Run: ./gradlew clean :micrometer-registry-statsd:shadowJar --build-cache
  3. Run the same command again: ./gradlew clean :micrometer-registry-statsd:shadowJar --build-cache
  4. Observe that shadowJar is re-executed instead of FROM-CACHE

Analysis

This issue was introduced when micrometer upgraded from Shadow 8.3.9 to 9.3.2. With Shadow 8.x, shadowJar was not part of the assemble lifecycle and was not affected. With Shadow 9.x, shadowJar is automatically added to assemble, exposing this caching regression.

The ShadowJar task's @TaskAction (copy() method) calls from(archiveOperations.zipTree(file)) and from(file) dynamically during execution. While the includedDependencies are properly tracked with @Classpath, the interaction between the parent Jar task's CopySpec tracking and the dynamic from() calls during execution may cause cache key instability.

Build scan evidence

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions