Skip to content

Upgrade Shadow plugin to 9.4.2#11730

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 6 commits into
masterfrom
bdu/upgrade-shadow-plugin-9-4-2
Jul 3, 2026
Merged

Upgrade Shadow plugin to 9.4.2#11730
gh-worker-dd-mergequeue-cf854d[bot] merged 6 commits into
masterfrom
bdu/upgrade-shadow-plugin-9-4-2

Conversation

@bric3

@bric3 bric3 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

What Does This Do

Upgrades the Gradle Shadow plugin from 8.3.9 to 9.4.2 in the main build.

The build wiring is updated for Shadow 9 APIs and behavior:

  • use lazy configuration providers for ShadowJar configuration inputs where practical
  • make shared dependency filtering explicit through a reusable Action
  • use regex dependency filter patterns where Shadow 9 no longer treats empty module/version fields as broad wildcards
  • make duplicate handling explicit for service-file transforms, license metadata, and known identical instrumentation classes
  • preserve the previous agent manifest shape by disabling automatic Multi-Release manifest inheritance
  • apply the same required Shadow 9 adjustments to smoke-test modules that run in the main Gradle build

Motivation

Shadow 9 brings several build-pipeline fixes that are useful for this project:

Additional Notes

bric3/jardiff was used between a master 11646d3 agent jar and this this branch's agent jar using ASM textifier output.

$ jardiff \
    -c classdata \
    --class-text-producer=asm-textifier \
    --color=never \
    master/dd-java-agent/build/libs/dd-java-agent-1.64.0-SNAPSHOT.jar \
    shadow-9/dd-java-agent/build/libs/dd-java-agent-1.64.0-SNAPSHOT.jar
--- ci-visibility/org/jacoco/core/runtime/LoggerRuntime.classdata
+++ ci-visibility/org/jacoco/core/runtime/LoggerRuntime.classdata
@@ -107,9 +107,9 @@
     ALOAD 5
     SIPUSH 184
     LDC "datadog/trace/bootstrap/PatchLogger"
     LDC "getLogger"
-    LDC "(Ljava/lang/String;)Ljava/util/logging/Logger;"
+    LDC "(Ljava/lang/String;)Ldatadog/trace/bootstrap/PatchLogger;"
     ICONST_0
     INVOKEVIRTUAL datadog/instrument/asm/MethodVisitor.visitMethodInsn (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
    L4
     LINENUMBER 100 L4

The difference is in a string constant inside JaCoCo’s LoggerRuntime, not in PatchLogger.java itself.

Shadow 9.2+ started relocating descriptor-shaped string constants. So this LDC changed:

 LDC "datadog/trace/bootstrap/PatchLogger"
 LDC "getLogger"
-LDC "(Ljava/lang/String;)Ljava/util/logging/Logger;"
+LDC "(Ljava/lang/String;)Ldatadog/trace/bootstrap/PatchLogger;"

That comes from the org.jacoco.core.runtime.LoggerRuntime class included via :dd-java-agent:agent-ci-visibility.

Before Shadow 9, relocation had already changed the method owner to datadog/trace/bootstrap/PatchLogger, but the descriptor string still said the method returned java.util.logging.Logger. That describes a method that does not exist: PatchLogger.getLogger(String):Logger. Shadow 9 rewrites the descriptor too, so generated bytecode calls the real method: PatchLogger.getLogger(String):PatchLogger, which matches datadog.trace.bootstrapPatchLogger in :dd-java-agent:agent-bootstrap.

https://github.com/DataDog/dd-trace-java/blob/987a0eba81a1121ea037005640cd0f407aaf5389/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/PatchLogger.java#L16-L19

In my opinion this looks like a correctness fix for that generated-accessor path, not a behavioral regression. It is also aligned with the agent relocation rule that intentionally redirects java.util.logging.Logger to PatchLogger to avoid JUL initialization during premain:

https://github.com/DataDog/dd-trace-java/blob/987a0eba81a1121ea037005640cd0f407aaf5389/dd-java-agent/build.gradle#L114-L116

Coverage-wise:

  • The Maven and Gradle smoke tests cover the real CI Visibility JaCoCo integration path: they enable the JaCoCo plugin version and assert received coverages/reports.

    @TableTest({
    "scenario | projectName | mavenVersion | expectedEvents | expectedCoverages | expectSuccess | testsSkipping | flakyRetries | jacocoCoverage | commandLineParams | minSupportedJavaVersion",
    "succeed-base | test_successful_maven_run | {3.5.4, 3.6.3, 3.8.8, 3.9.9} | 5 | 1 | true | true | false | true | [] | 8 ",
    "succeed-surefire-3.0.0-j8 | test_successful_maven_run_surefire_3_0_0 | 3.9.9 | 5 | 1 | true | true | false | true | [] | 8 ",
    "succeed-surefire-3.0.0-j17 | test_successful_maven_run_surefire_3_0_0 | latest | 5 | 1 | true | true | false | true | [] | 17 ",
    "succeed-surefire-3.5.0-j8 | test_successful_maven_run_surefire_3_5_0 | 3.9.9 | 5 | 1 | true | true | false | true | [] | 8 ",
    "succeed-surefire-3.5.0-j17 | test_successful_maven_run_surefire_3_5_0 | latest | 5 | 1 | true | true | false | true | [] | 17 ",
    "succeed-builtin-coverage | test_successful_maven_run_builtin_coverage | 3.9.9 | 5 | 1 | true | true | false | false | [] | 8 ",
    "succeed-jacoco-argline | test_successful_maven_run_with_jacoco_and_argline | 3.9.9 | 5 | 1 | true | true | false | true | [] | 8 ",
    "succeed-cucumber | test_successful_maven_run_with_cucumber | 3.9.9 | 4 | 1 | true | false | false | true | [] | 8 ",
    "failed-flaky-retries | test_failed_maven_run_flaky_retries | 3.9.9 | 8 | 5 | false | false | true | true | [] | 8 ",
    "succeed-junit-platform | test_successful_maven_run_junit_platform_runner | 3.9.9 | 4 | 0 | true | false | false | false | [] | 8 ",
    "succeed-arg-line-property | test_successful_maven_run_with_arg_line_property | 3.9.9 | 4 | 0 | true | false | false | false | [\"-DargLine='-Dmy-custom-property=provided-via-command-line'\"] | 8 ",
    "succeed-multi-forks-j8 | test_successful_maven_run_multiple_forks | 3.9.9 | 5 | 1 | true | true | false | true | [] | 8 ",
    "succeed-multi-forks-j17 | test_successful_maven_run_multiple_forks | latest | 5 | 1 | true | true | false | true | [] | 17 "
    })
    @ParameterizedTest
    void testMavenRun(
    String projectName,

    @TableTest({
    "scenario | gradleVersion | projectName | configurationCache | successExpected | flakyRetries | expectedTraces | expectedCoverages",
    "succeed-new-8.3 | 8.3 | test-succeed-new-instrumentation | {false, true} | true | false | 5 | 1 ",
    "succeed-new-8.9 | 8.9 | test-succeed-new-instrumentation | {false, true} | true | false | 5 | 1 ",
    "succeed-new-latest | latest | test-succeed-new-instrumentation | {false, true} | true | false | 5 | 1 ",
    "succeed-multi-module-new | latest | test-succeed-multi-module-new-instrumentation | false | true | false | 7 | 2 ",
    "succeed-multi-forks-new | latest | test-succeed-multi-forks-new-instrumentation | false | true | false | 6 | 2 ",
    "skip-new | latest | test-skip-new-instrumentation | false | true | false | 2 | 0 ",
    "failed-new | latest | test-failed-new-instrumentation | false | false | false | 4 | 0 ",
    "corrupted-config-new | latest | test-corrupted-config-new-instrumentation | false | false | false | 1 | 0 ",
    "succeed-junit-5 | latest | test-succeed-junit-5 | false | true | false | 5 | 1 ",
    "failed-flaky-retries | latest | test-failed-flaky-retries | false | false | true | 8 | 0 ",
    "succeed-gradle-plugin-test | latest | test-succeed-gradle-plugin-test | false | true | false | 5 | 0 "
    })
    @ParameterizedTest
    void testNew(
    String gradleVersion,

  • That path uses the external JaCoCo agent runtime, which our instrumentation targets via org.jacoco.agent.rt.internal...:

    @Override
    public ElementMatcher<TypeDescription> hierarchyMatcher() {
    // The jacoco javaagent jar that is published relocates internal classes to an "obfuscated"
    // package name ex. org.jacoco.agent.rt.internal_72ddf3b.core.instr.Instrumenter
    return nameStartsWith("org.jacoco.agent.rt.internal")
    .and(nameEndsWith(".core.instr.Instrumenter"));
    }

  • The shaded org.jacoco.core dependency in agent-ci-visibility appears used for parsing/analyzing coverage data and reports, not for LoggerRuntime:

    private static ExecutionDataStore parseCoverageData(byte[] rawCoverageData) {
    if (rawCoverageData == null) {

    import org.jacoco.core.analysis.Analyzer;
    import org.jacoco.core.data.ExecutionDataStore;
    import org.slf4j.Logger;

Contributor Checklist

Jira ticket: [PROJ-IDENT]

bric3 added 2 commits June 24, 2026 17:48
* Adapt custom ShadowJar wiring to the lazy API. Configuration lists now
  use providers around `configurations.named(...)`, and Shadow resolves
  `Configuration` values directly.

  GradleUp/shadow#1044
  GradleUp/shadow#1045

* Keep filtering explicit. Shadow 9 changed `DependencyFilter`
  overloads, so shared filters run in Shadow `dependencies` blocks.
  Empty module/version fields no longer act as broad wildcards, so
  group-wide excludes use full group/module/version regex notation.
  That keeps dependencies meant to stay external out of shaded jars;
  otherwise downstream jars can get partly relocated API copies, such as
  SLF4J, and lose their real binding.

  https://gradleup.com/shadow/configuration/dependencies/#using-regex-patterns-to-filter-dependencies
  GradleUp/shadow#1328

* Keep `mergeServiceFiles` users on `DuplicatesStrategy.INCLUDE` before
  transformers run, then drop unrelated duplicate resources with file
  matching. Shadow 9 honors duplicate strategies during transforms.

  GradleUp/shadow#1233
  GradleUp/shadow#1617

* Disable automatic Multi-Release manifest inheritance for the agent jar
  to keep the previous manifest shape.

  GradleUp/shadow#1239
  GradleUp/shadow#1675

* Note the relocation output change. Shadow 9.2+ rewrites more
  descriptor-shaped string constants, which explains the observed
  `LoggerRuntime` LDC descriptor change.

  GradleUp/shadow#1714
  GradleUp/shadow#1731

* Apply the same API and resource handling changes to smoke-test modules
  that run in the main Gradle build.
@bric3 bric3 added type: enhancement Enhancements and improvements tag: no release notes Changes to exclude from release notes comp: tooling Build & Tooling labels Jun 24, 2026
@bric3 bric3 marked this pull request as ready for review June 24, 2026 19:28
@bric3 bric3 requested review from a team as code owners June 24, 2026 19:28
@bric3 bric3 requested review from Copilot, daniel-mohedano, daniel-romano-DD, jandro996, leoromanovsky, mcculls, typotter and ygree and removed request for a team and Copilot June 24, 2026 19:28

@daniel-mohedano daniel-mohedano left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM from CIVis side! AFAIK we don't use JaCoCo's LoggerRuntime at all, we rely on jacoco for parsing/analyzing coverage reports, and our smoke tests already cover the expected behavior for the instrumentation. So agreed it shouldn't be a regression

@bric3 bric3 requested a review from amarziali June 25, 2026 14:25
Comment thread dd-java-agent/instrumentation/build.gradle

@AlexeyKuznetsov-DD AlexeyKuznetsov-DD left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, nice improvement!
Left minor comments.

Comment thread buildSrc/call-site-instrumentation-plugin/build.gradle.kts Outdated
Comment thread buildSrc/call-site-instrumentation-plugin/build.gradle.kts Outdated
Comment thread buildSrc/modifiable-config-agent/build.gradle.kts Outdated
Comment on lines +30 to +38
filesNotMatching([
'META-INF/services/**',
'META-INF/spring.handlers',
'META-INF/spring.schemas',
'META-INF/spring.tooling',
'META-INF/spring.factories',
]) {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: this pattern looks like repeating several times, any ideas how to reuse code?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I think it's fine, this is happening in smoke tests because these projects are using the main build.

Comment thread build.gradle.kts Outdated
Comment thread buildSrc/call-site-instrumentation-plugin/build.gradle.kts Outdated
Comment thread dd-java-agent/instrumentation/build.gradle
@bric3

bric3 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

/merge

@gh-worker-devflow-routing-ef8351

gh-worker-devflow-routing-ef8351 Bot commented Jul 3, 2026

Copy link
Copy Markdown

View all feedbacks in Devflow UI.

2026-07-03 07:30:20 UTC ℹ️ Start processing command /merge


2026-07-03 07:30:28 UTC ℹ️ MergeQueue: pull request added to the queue

The expected merge time in master is approximately 2h (p90).


2026-07-03 08:35:27 UTC ℹ️ MergeQueue: This merge request was merged

@gh-worker-dd-mergequeue-cf854d gh-worker-dd-mergequeue-cf854d Bot merged commit 2734057 into master Jul 3, 2026
587 checks passed
@gh-worker-dd-mergequeue-cf854d gh-worker-dd-mergequeue-cf854d Bot deleted the bdu/upgrade-shadow-plugin-9-4-2 branch July 3, 2026 08:35
@github-actions github-actions Bot added this to the 1.64.0 milestone Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: tooling Build & Tooling tag: no release notes Changes to exclude from release notes type: enhancement Enhancements and improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants