Skip to content

Build smoke-test apps via Gradle Tooling API for Gradle 9 readiness - #11404

Closed
bric3 wants to merge 15 commits into
masterfrom
bdu/smoke-test-tooling-api-build
Closed

Build smoke-test apps via Gradle Tooling API for Gradle 9 readiness#11404
bric3 wants to merge 15 commits into
masterfrom
bdu/smoke-test-tooling-api-build

Conversation

@bric3

@bric3bric3 commented May 18, 2026

Copy link
Copy Markdown
Contributor

For easier review see

New Smoke test Plugin

Smoke tests fixes

What Does This Do

Introduces a new build-logic/ included build hosting the dd-trace-java.smoke-test-app plugin, which builds smoke-test applications via the Gradle Tooling API in a nested daemon with a pinned Gradle version and Java toolchain — without committing per-application gradlew wrappers.

Fourteen smoke-test modules that pin Spring Boot 2.x are converted to this new plugin so the root build can move to Gradle 9 (the Spring Boot Gradle plugin <3.5.0 calls Configuration.getUploadTaskName(), which is removed in Gradle 9).

ModuleSB versionNotes
apm-tracing-disabled2.7.18forwards dd-trace-api jar
kafka-22.7.15forwards iast-util jar
openfeature2.7.15Java 11; forwards feature-flagging-api jar
spring-boot-2.7-webflux2.7.4task renamed webfluxBuild
springboot-freemarker2.7.15+ copyAppResources for FS templates
springboot-java-112.7.15Java 11; forwards iast-util-11
springboot-java-172.7.15Java 17; forwards iast-util-17
springboot-jetty-jsp2.7.15
springboot-jpa2.6.0Lombok
springboot-thymeleaf2.7.15
springboot-tomcat2.5.12Ivy Tomcat download stays in inner build
springboot-tomcat-jsp2.7.15
springboot-velocity2.7.15+ copyAppResources for FS templates
datastreams/kafkaschemaregistry2.6.3Spring Boot plugin removed (unused)

Motivation

Gradle 9.5 readiness requires every direct subproject of the root build to be compatible with Gradle 9. The Spring Boot Gradle plugin pinned by some smoke tests can't run on Gradle 9, so those apps have to be built out-of-process.

This is an alternative path to #11379, which solved the same problem by committing 22 per-application Gradle 8.14.5 wrappers and shelling out via Exec. In #11379 this created many gradle wrappers, also some Exec tasks forwarded project jars without declaring them as task inputs (stale-cache risk). The approach here addresses both: no wrappers, and forwarded jars are modelled as resolvable Configurations that Gradle wires as task inputs / task dependencies automatically.

Effort part of #10402, #11272

Additional Notes

There's a new included build build-logic/ with one subproject (smoke-test) for a single plugin id (dd-trace-java.smoke-test-app). The reason for this are

  • If dd-trace-java.smoke-test-app was in buildSrc it would add its dependencies in anything that consumes buildSrc plugins. Given this is very specific to some smoke tests, it is preferable to isolate it.
  • Included builds are the Gradle recommended way, so it's where buildSrc/ will be. They are some issue with the (legacy) buildSrc/ way, more details here, in Gradle best practices. Initiating this project now makes sense.

Structurally this new plugin consists of

  • A NestedGradleBuild task type wraps the GradleConnector from the Gradle Tooling API. It pins the nested Gradle distribution and JDK and declares the application directory as @InputFiles and the produced artifact tree as @OutputDirectory.
  • A smokeTestApp { application { ... } } project extension that will be used to configure the task and wiring. If a consumer does not use application { ... }, the plugin is a no-op and the task type can be registered manually.
  • Forwarded root-build jars are exposed via projectJar(name, project), which creates a resolvable Configuration with isTransitive = false — no evaluationDependsOn and no afterEvaluate.
  • The freemarker and velocity modules also need a small Copy task to mirror the nested build's resources/main into the outer build dir, because their controller resolves templates via filesystem paths rather than the classpath.

Noteworthy as well this PR took another route than #11272, in there Spring Boot Gradle plugin is sidestepped, the smoke build emits a flat shadowJar. THis results in jars that have different layout from Spring Boot jars (Spring Boot Class Loader to accommodate the boot jar, BOOT-INF, layered jar). While this approach keeps "thinner" impact, it somewhat makes smoke test not testing exactly the same thing.

Contributor Checklist

Jira ticket: [PROJ-IDENT]

Note:Once your PR is ready to merge, add it to the merge queue by commenting /merge./merge -c cancels the queue request. /merge -f --reason "reason" skips all merge queue checks; please use this judiciously, as some checks do not run at the PR-level. For more information, see this doc.

bric3and others added 12 commits May 18, 2026 15:50
Adds a new included build `build-logic/` hosting a single subproject
`smoke-test` that exposes the `dd-trace-java.smoke-test-app` plugin and
its `NestedGradleBuild` task type.
The task runs a nested Gradle build via the Tooling API:
- pins the nested Gradle version (no committed per-application wrappers),
- uses the configured Java toolchain for the nested daemon,
- forwards artifact paths from the root build as `-P<name>=<path>`,
- redirects the nested `buildDir` via `-PappBuildDir=<path>` so outputs
land under the outer project's build directory.
Smoke-test modules with Spring Boot plugin versions incompatible with
Gradle 9 will use this plugin instead of a committed Gradle 8 wrapper
(see PR #11379 for the wrapper-based alternative).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Spring Boot Gradle plugin 2.x calls `Configuration.getUploadTaskName()`,
removed in Gradle 9, so springboot-jpa (Spring Boot 2.6.0) cannot stay as a
direct subproject of the Gradle 9 root build.
Extract the application source into a self-contained `application/` Gradle
project pinned to Spring Boot 2.6.0 and built via the new
`dd-trace-java.smoke-test-app` plugin from `build-logic/`. The plugin uses
the Gradle Tooling API to run the nested build with a pinned Gradle version
(8.14.5) and the Java 8 toolchain — no committed `gradlew` wrapper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…registry
The Spring Boot Gradle plugin was applied but the module never produced a
bootJar/bootWar — it ships a shadow jar instead. Removing the plugin
eliminates a Gradle-9 blocker (the plugin's pre-3.5.0 versions call
`Configuration.getUploadTaskName()`, removed in Gradle 9) with no
behavioural change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… Gradle build
These three Spring Boot 2.7.15 smoke tests fail under Gradle 9 because the
Spring Boot plugin (pre-3.5.0) calls `Configuration.getUploadTaskName()`,
removed in Gradle 9. Extract the application source into self-contained
`application/` Gradle projects built via the nested-build plugin from
`build-logic/`, which pins Gradle 8.14.5 and the Java 8 toolchain for the
inner build.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extract Spring Boot 2.7.15 application sources into self-contained
`application/` Gradle projects built via the nested-build plugin from
`build-logic/`, so the root build can run on Gradle 9 without the Spring
Boot plugin's `Configuration.getUploadTaskName()` regression.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spring Boot 2.5.12 with the Ivy-downloaded Tomcat server. Move the inline
plugin + Ivy repo + unzip task into a self-contained `application/` Gradle
project built via the nested-build plugin (Gradle 8.14.5, Java 8). The
outer build keeps the test source and forwards the produced war path plus
the Tomcat install directory as system properties.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Spring Boot 2.7.15 app depends on the iast-util jar produced by the
root build. Extract the application into a self-contained `application/`
project and forward `iast-util.jar` via `-PiastUtilJar=<path>` (tracked
as a task input so the nested build re-runs when the upstream jar changes).
`spring-kafka-test` is pinned to 2.8.11 (the version the Spring Boot BOM
previously resolved); the test module no longer applies the BOM.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spring Boot 2.7.15, Java 11. Extract the application into a self-contained
`application/` project; forward the `feature-flagging-api` jar from the
root build via `-PfeatureFlaggingApiJar=<path>` (tracked as a task input).
The inner build pins the OpenFeature SDK explicitly because the dependency
is `api`-scoped in feature-flagging-api but is not transitively resolved
when its jar is passed as a `files()` dependency.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spring Boot 2.7.15 wrapping starter-web 2.2.0, Java 11. Extract the
application into a self-contained `application/` project and forward
`iast-util-11.jar` from the root build via `-PiastUtil11Jar=<path>`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Same shape as springboot-java-11: Spring Boot 2.7.15 plugin wrapping
starter-web 2.2.0, Java 17, with `iast-util-17.jar` forwarded from the
root build via `-PiastUtil17Jar=<path>`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spring Boot 2.7.18, Java 8. Extract the application into a self-contained
`application/` project and forward `dd-trace-api.jar` from the root build
via `-PapiJar=<path>`.
The non-flaky tests pass locally; the `@Flaky`-marked
`ApmTracingDisabledSamplingSmoke{V04,V1}Test` variants remain skipped in
CI as today.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lugin
This module already had its application source in `application/`, built
via an `Exec` task invoking the root `gradlew`. With the root build moving
to Gradle 9 (incompatible with Spring Boot plugin 2.x), the nested build
must instead pin its own Gradle version. Swap the `Exec` task for the
`NestedGradleBuild` task type from the `build-logic:smoke-test` plugin.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bric3bric3 added type: feature Enhancements and improvements tag: no release notes Changes to exclude from release notes comp: tooling Build & Tooling tag: ibm IBM JVM related tag: ai generated Largely based on code generated by an AI or LLM tag: do not merge Do not merge changes and removed tag: ibm IBM JVM related labels May 18, 2026
@datadog-prod-us1-3

datadog-prod-us1-3Bot commented May 19, 2026

Copy link
Copy Markdown

Pipelines

Fix all issues with BitsAI

⚠️ Warnings

🚦 5 Pipeline jobs failed

DataDog/apm-reliability/dd-trace-java | build_tests: [:smokeTest, smoke, -Xms256M -Xmx1024M] View in DatadogGitLab

🔧 Fix in code (Fix with Cursor). IncompatibleSpockVersionException: Spock 2.4.0-groovy-3.0 is not compatible with Groovy 4.0.29 during task ':dd-smoke-tests:gradle:compileTestGroovy'.

DataDog/apm-reliability/dd-trace-java | check_smoke 1/4 View in DatadogGitLab

🔧 Fix in code (Fix with Cursor). Execution failed for task ':dd-smoke-tests:spring-boot-3.0-webflux:webfluxBuild30' due to failed dependency resolution: 'java.util.Set org.gradle.api.artifacts.LenientConfiguration.getArtifacts(org.gradle.api.specs.Spec)'

DataDog/apm-reliability/dd-trace-java | check_smoke 3/4 View in DatadogGitLab

🔄 Retry job. This looks flaky and may succeed on retry. Execution failed for task ':compileJava'. Error: Failed to notify dependency resolution listener.

View all 5 failed jobs.

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 922ab43 | Docs | Datadog PR Page | Give us feedback!

bric3and others added 2 commits May 19, 2026 14:51
Gradle 9.5 added a `DependencyHandler.project(String)` overload that
returns a `ProjectDependency`. Inside a `dependencies { }` block, that
overload now shadows the `Project.project(String)` accessor that
previously resolved via Groovy fallback. Result:
`project(':foo').sourceSets` no longer reaches the producing project's
source sets — it hits a `DefaultProjectDependency` and fails with
"unknown property 'sourceSets'".
`dd-smoke-tests/debugger-integration-tests/build.gradle:21` used
`project(':dd-java-agent:agent-debugger').sourceSets.test.output` to
pull two helper classes (`LogProbeTestHelper`, `MoshiSnapshotTestHelper`)
from `agent-debugger`'s test sources.
Apply the canonical Gradle 9.5 fix (see #11367): expose the helpers via
the `java-test-fixtures` plugin on `agent-debugger`. The helpers move
from `src/test/java/com/datadog/debugger/util/` to
`src/testFixtures/java/com/datadog/debugger/util/` (same package), and
the consumer pulls them in via
`testImplementation testFixtures(project(':dd-java-agent:agent-debugger'))`.
The 15 existing in-project consumers (test classes inside agent-debugger)
keep working because the testFixtures source set is automatically on the
`test` source set's classpath.
This unblocks running the root build on Gradle 9.5.1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Combined with the smoke-test plugin work earlier on this branch (Spring
Boot 2.x extracted into nested-build subprojects running under a Gradle
8.14.5 daemon via the Tooling API) and the agent-debugger
java-test-fixtures migration, this unblocks the root build on
Gradle 9.5.1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bric3
bric3force-pushed the bdu/smoke-test-tooling-api-build branch from fe8cd93 to 132c13dCompareMay 19, 2026 12:51
…plugin
The wildfly and rum:wildfly-15 smoke tests built their EAR via an `Exec`
task invoking the root `gradlew` with `JAVA_HOME=8` (or whatever the
parent shell had). Once the root wrapper moved to Gradle 9, that pattern
broke — Gradle 9 requires a JDK 17 daemon, which then can't load the
JDK 8-targeted application.
Swap both `earBuild` tasks for the `NestedGradleBuild` task type from
the `build-logic:smoke-test` plugin so the nested EAR build runs on a
Gradle 8.14.5 daemon with the Java 8 toolchain. `dd-trace-api.jar` is
forwarded through the plugin's `projectJar(...)` helper.
The surrounding wildfly orchestration (unzip the server zip, copy the
EAR into `standalone/deployments`, `Test.dependsOn 'deploy'`) is
unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@pr-commenter

Copy link
Copy Markdown

Debugger benchmarks

Parameters

BaselineCandidate
baseline_or_candidatebaselinecandidate
ci_job_date17791966501779196997
end_time2026-05-19T13:18:552026-05-19T13:24:43
git_branchmasterbdu/smoke-test-tooling-api-build
git_commit_sha198a35d922ab43
start_time2026-05-19T13:17:312026-05-19T13:23:18
See matching parameters
BaselineCandidate
ci_job_id16944700171694470017
ci_pipeline_id113952583113952583
cpu_modelIntel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHzIntel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
git_commit_date17791958041779195804

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 9 metrics, 6 unstable metrics.

See unchanged results
scenarioΔ mean agg_http_req_duration_minΔ mean agg_http_req_duration_p50Δ mean agg_http_req_duration_p75Δ mean agg_http_req_duration_p99Δ mean throughput
scenario:noprobeunstable
[-31.250µs; +24.224µs] or [-10.490%; +8.132%]
unstable
[-48.386µs; +33.533µs] or [-14.095%; +9.769%]
unstable
[-62.100µs; +42.265µs] or [-17.195%; +11.703%]
unstable
[+51.983µs; +277.080µs] or [+4.274%; +22.781%]
same
scenario:basicsamesamesameunstable
[-4.081µs; +268.086µs] or [-0.370%; +24.321%]
unstable
[-99.231op/s; +221.182op/s] or [-4.068%; +9.068%]
scenario:loopsameunsure
[+2.146µs; +14.012µs] or [+0.024%; +0.156%]
unsure
[+0.428µs; +9.998µs] or [+0.005%; +0.110%]
samesame
Request duration reports for reports
gantt
title reports - request duration [CI 0.99] : candidate=None, baseline=None
dateFormat X
axisFormat %s
section baseline
noprobe (343.272 µs) : 295, 392
. : milestone, 343,
basic (297.507 µs) : 291, 304
. : milestone, 298,
loop (8.976 ms) : 8970, 8982
. : milestone, 8976,
section candidate
noprobe (335.846 µs) : 310, 362
. : milestone, 336,
basic (296.371 µs) : 290, 303
. : milestone, 296,
loop (8.984 ms) : 8979, 8990
. : milestone, 8984,
Loading
  • baseline results
ScenarioRequest median duration [CI 0.99]
noprobe343.272 µs [294.683 µs, 391.861 µs]
basic297.507 µs [290.738 µs, 304.276 µs]
loop8.976 ms [8.97 ms, 8.982 ms]
  • candidate results
ScenarioRequest median duration [CI 0.99]
noprobe335.846 µs [309.914 µs, 361.779 µs]
basic296.371 µs [289.697 µs, 303.046 µs]
loop8.984 ms [8.979 ms, 8.99 ms]

@bric3

Copy link
Copy Markdown
ContributorAuthor

superseded by smaller prs

@bric3bric3 closed this May 19, 2026
@bric3bric3 mentioned this pull request May 21, 2026
19 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: toolingBuild & Toolingtag: ai generatedLargely based on code generated by an AI or LLMtag: do not mergeDo not merge changestag: no release notesChanges to exclude from release notestype: featureEnhancements and improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@bric3