Extract Spring Boot 2.x app source into nested-build subprojects#11408
Conversation
Adds a new included build `build-logic/` hosting a single subproject
`smoke-test` that exposes the `dd-trace-java.smoke-test-app` plugin.
The plugin contributes:
- `NestedGradleBuild` task type that runs a nested Gradle build via the
Gradle Tooling API. It 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>`, and redirects the nested `buildDir` via
`-PappBuildDir=<path>` so outputs land under the outer project's build
directory.
- `smokeTestApp` project extension with an `application { ... }` block
that registers the `NestedGradleBuild` task, wires it into every `Test`
task via `dependsOn` + a `jvmArgumentProvider` for the produced
artifact's system property. Consumers can also register
`NestedGradleBuild` directly when they need more control; the plugin
is a no-op until `application` or a manual registration is done.
- `projectJar(name, project)` helper that forwards a sibling project's
jar to the nested build through a resolvable `Configuration` (avoids
`evaluationDependsOn` and the cross-project access ordering issues).
The plugin is verified with JUnit 5 unit tests (`ProjectBuilder`) and
end-to-end tests that drive the Tooling API path through the Gradle Test
Kit with a temporary Kotlin-DSL test project.
`build-logic/settings.gradle.kts` references the existing
`gradle/libs.versions.toml` catalog (mirroring `buildSrc/`) so the
plugin can use the same library coordinates as the rest of the repo.
The Gradle libs Maven repository (`https://repo.gradle.org/gradle/libs-releases`,
scoped to `org.gradle:`) is added to the root build's `pluginManagement`
and to `gradle/repositories.gradle` so the Tooling API jar resolves.
Smoke-test modules with Spring Boot plugin versions incompatible with
Gradle 9 will use this plugin in follow-up PRs instead of a committed
Gradle 8 wrapper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
b924cb8 to
149a0ec
Compare
…14.5
Set conventions on `smokeTestApp`:
- `gradleVersion` defaults to `"8.14.5"` (Gradle 8 last release; pinned because
Spring Boot plugin pre-3.5 calls `Configuration.getUploadTaskName()`, removed
in Gradle 9).
- `javaLauncher` defaults to a JDK 21 toolchain (the version the root build
requires for its own Gradle 9 migration; standardising the nested daemon on
the same JDK avoids requiring an extra toolchain on dev machines and CI
runners).
Consumers that need a different JDK or Gradle version still override
explicitly. The inner build script is responsible for pinning the produced
bytecode level (`java { sourceCompatibility = JavaVersion.VERSION_1_8 }` or
similar) — Gradle adds `--release N` automatically when source/target differs
from the daemon JVM.
`JavaToolchainService` is now injected into the extension; this works in any
project where a `java*` (or related) plugin is applied. Smoke-test modules
already apply `gradle/java.gradle`, which applies `java`, so the convention
resolves on first read.
Public defaults exposed as `DEFAULT_NESTED_GRADLE_VERSION` and
`DEFAULT_NESTED_JAVA_VERSION` constants so the values are discoverable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
c6d9744 to
1562192
Compare
This comment has been minimized.
This comment has been minimized.
9e60b33 to
6364e58
Compare
There was a problem hiding this comment.
note: settings.gradle in nested projects have somewhat the same duplicated configuration around repo proxies. And ci cache. I have no proper solution yet, but this should come as a follow-up work.
…ugin
Switch the plugin sources and unit tests over to the typed
`org.gradle.kotlin.dsl` extension functions where they replace
`::class.java` boilerplate:
- `tasks.register(name, Type::class.java) { … }` → `tasks.register<Type>(name) { … }`
- `tasks.withType(Type::class.java).configureEach { … }` → `tasks.withType<Type>().configureEach { … }`
- `extensions.create("name", Type::class.java)` → `extensions.create<Type>("name")`
- `extensions.getByType(Type::class.java)` → `extensions.getByType<Type>()`
- `extensions.findByName("name")` (followed by `isInstanceOf`) → `extensions.findByType<Type>()`
- `project.plugins.apply(Plugin::class.java)` → `project.apply<Plugin>()` (PluginAware)
- `objects.newInstance(Type::class.java)` → `objects.newInstance<Type>()`
Also drop the six `captured*` local variables in `SmokeTestAppExtension.application` —
inside `tasks.register<NestedGradleBuild>(taskName) { … }` the outer extension's
properties are now reached via `this@SmokeTestAppExtension.<prop>` directly.
No behavioural change; the 9 plugin tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ild subprojects The Spring Boot Gradle plugin is incompatible with Gradle 9 for all versions before 3.5.0 because it calls `Configuration.getUploadTaskName()`, a method removed in Gradle 9. Twelve smoke-test modules were direct Gradle subprojects that applied the Spring Boot plugin to build their bootJar / bootWar artefact. They cannot stay as subprojects of the Gradle 9 root build. For each of these modules, the application source is extracted into a new `application/` subdirectory that is a fully self-contained Gradle project (`settings.gradle` + `build.gradle`). The outer module keeps the test source and delegates the application build to the `dd-trace-java.smoke-test-app` plugin from `build-logic/` (added in the parent infrastructure PR), which runs the nested build via the Gradle Tooling API pinned to Gradle 8.14.5 — no committed `gradlew` wrapper. Modules converted (bootJar): - springboot-thymeleaf (Spring Boot 2.7.15, Java 8) - springboot-freemarker (Spring Boot 2.7.15 plugin / 1.5.18 starter, Java 8) - springboot-velocity (Spring Boot 2.7.15 plugin / 1.5.18 starter, Java 8) - springboot-java-11 (Spring Boot 2.7.15, Java 11; passes iast-util-11 jar) - springboot-java-17 (Spring Boot 2.7.15, Java 17; passes iast-util-17 jar) - openfeature (Spring Boot 2.7.15, Java 11; passes feature-flagging-api jar) - kafka-2 (Spring Boot 2.7.15, Java 8; passes iast-util jar) - apm-tracing-disabled (Spring Boot 2.7.15, Java 8; passes dd-trace-api jar) Modules converted (bootWar): - springboot-jpa (Spring Boot 2.6.0, Java 8; Lombok) - springboot-tomcat-jsp (Spring Boot 2.7.15, Java 8; JSP webapp) - springboot-jetty-jsp (Spring Boot 2.7.15, Java 8; JSP webapp) - springboot-tomcat (Spring Boot 2.5.12, Java 8; Ivy Tomcat download + unzip) Where an application module depends on a project artifact from the main build (e.g. iast-util-11, dd-trace-api), the jar is forwarded via the plugin's `projectJar(name, project)` helper — a resolvable `Configuration` that establishes the upstream task dependency automatically. The inner build picks it up via `findProperty(name)` and adds it as `implementation files(...)`. The `spring-kafka-test` test dependency in kafka-2 is pinned to 2.8.11 (the version previously resolved from the Spring Boot BOM) since the outer test module no longer applies that BOM. For springboot-freemarker and springboot-velocity, the `XssController` loads templates from `resources/main/templates` relative to the test JVM's working directory. After moving sources into `application/`, those files land at `build/application/resources/main/templates/` instead of `build/resources/main/templates/`. Each affected outer build registers a `copyAppResources` Copy task that mirrors the inner build's processed resources into the outer build dir so the runtime path still resolves. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6364e58 to
6b7e87c
Compare
AlexeyKuznetsov-DD
left a comment
There was a problem hiding this comment.
Overall LGTM, left minor comments and questions.
I feel that all build files should have more comments around why things done in that way, also maybe there is a way to minimize config by using reasonable defaults here and there.
| smokeTestApp { | ||
| application { | ||
| taskName = 'bootJar' | ||
| artifactPath = 'libs/apm-tracing-disabled-smoketest.jar' |
There was a problem hiding this comment.
Just as idea: how about to calculate default name of artifactPath from module name by template?
Like (pseudocode): libs/$moduleName-smoke-test.jar? With all needed .toLowerCase() and replace if needed. WDYT?
There was a problem hiding this comment.
good point, I'll take a look in a follow up pr
| buildCache { | ||
| local { | ||
| directory = "$sharedRootDir/workspace/build-cache" | ||
| } | ||
| } |
There was a problem hiding this comment.
Let's comment the knowledge behind such non-trivial-Gradle configs.
There was a problem hiding this comment.
Note existing smoke tests already had this for quite some time, it just follows what's been there, it seems to have been introduced by b34ccbc, and has been applied to other smoke tests, prior my changes.
The buildcache dir config referes to the root level cache that was introduced in f6ec1f5 #982
I'll add the comments in a follow-up pr.
| java { | ||
| sourceCompatibility = 11 | ||
| targetCompatibility = 11 | ||
| } |
There was a problem hiding this comment.
Just curious why Java 11 with old spring boot 2.7.15?
There was a problem hiding this comment.
The app was compiled with Java 11 before
dd-trace-java/dd-smoke-tests/openfeature/build.gradle
Lines 17 to 20 in 5181a21
There was a problem hiding this comment.
If app compiled with Java 11, maybe Gradle plugins can be bumped?
There was a problem hiding this comment.
Maybe, but I'd rather not disperse this effort. If needed this can be done in a later PR. I'll keep the comment open so we can go back it.
| def sharedRootDir = "$rootDir/../../../" | ||
| buildCache { | ||
| local { | ||
| directory = "$sharedRootDir/workspace/build-cache" |
There was a problem hiding this comment.
Just curious why in some projects sharedRootDir hardcoded, and some under isCI?
There was a problem hiding this comment.
Not quite sure, but I will remove those in a later PR as they are basically useless.
See #11408 (comment)
|
/merge |
|
View all feedbacks in Devflow UI.
The expected merge time in
The merge request has been interrupted because the build 0 took longer than expected. The current limit for the base branch 'master' is 120 minutes. |
Address review feedback on #11408: add comments explaining the legacy Spring Boot 2.7.x / OpenTracing pins, the iastUtilJar property wired from the outer build, the CI-only shared build cache (f6ec1f5 / #982, b34ccbc), the internal Maven mirror proxies, and the Java 11 baseline for the OpenFeature smoke test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match the review feedback applied on #11408: expand the terse comments on the nested settings.gradle files to explain the CI Maven mirror proxies and the CI-only shared build cache (f6ec1f5 / #982, b34ccbc), plus the Quarkus plugin version property forwarding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| // root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default | ||
| // per-user cache to avoid leaking entries into the repo tree. | ||
| if (isCI) { | ||
| def sharedRootDir = "$rootDir/../../../" |
There was a problem hiding this comment.
Just curious, why in some places sharedRooDir is under if (CI) and in some places it is not?
There was a problem hiding this comment.
Actually, the more I think about this, the more I think this build cache config is useless for nested smoke test projects. Given build cache is disabled by default and that the nested gradle jobs (existing or new via this PR) don't leverage the build-cache (there's neither --build-cache or org.gradle.caching=true). Consequently the buildCache { local { directory = … } } block is useless.
|
/merge |
|
View all feedbacks in Devflow UI.
The expected merge time in
|
chore(build-logic): add smoke-test plugin for nested Gradle builds
Adds a new included build `build-logic/` hosting a single subproject
`smoke-test` that exposes the `dd-trace-java.smoke-test-app` plugin.
The plugin contributes:
- `NestedGradleBuild` task type that runs a nested Gradle build via the
Gradle Tooling API. It 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>`, and redirects the nested `buildDir` via
`-PappBuildDir=<path>` so outputs land under the outer project's build
directory.
- `smokeTestApp` project extension with an `application { ... }` block
that registers the `NestedGradleBuild` task, wires it into every `Test`
task via `dependsOn` + a `jvmArgumentProvider` for the produced
artifact's system property. Consumers can also register
`NestedGradleBuild` directly when they need more control; the plugin
is a no-op until `application` or a manual registration is done.
- `projectJar(name, project)` helper that forwards a sibling project's
jar to the nested build through a resolvable `Configuration` (avoids
`evaluationDependsOn` and the cross-project access ordering issues).
The plugin is verified with JUnit 5 unit tests (`ProjectBuilder`) and
end-to-end tests that drive the Tooling API path through the Gradle Test
Kit with a temporary Kotlin-DSL test project.
`build-logic/settings.gradle.kts` references the existing
`gradle/libs.versions.toml` catalog (mirroring `buildSrc/`) so the
plugin can use the same library coordinates as the rest of the repo.
The Gradle libs Maven repository (`https://repo.gradle.org/gradle/libs-releases`,
scoped to `org.gradle:`) is added to the root build's `pluginManagement`
and to `gradle/repositories.gradle` so the Tooling API jar resolves.
Smoke-test modules with Spring Boot plugin versions incompatible with
Gradle 9 will use this plugin in follow-up PRs instead of a committed
Gradle 8 wrapper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chore(build-logic): default smokeTestApp to JDK 21 daemon + Gradle 8.14.5
Set conventions on `smokeTestApp`:
- `gradleVersion` defaults to `"8.14.5"` (Gradle 8 last release; pinned because
Spring Boot plugin pre-3.5 calls `Configuration.getUploadTaskName()`, removed
in Gradle 9).
- `javaLauncher` defaults to a JDK 21 toolchain (the version the root build
requires for its own Gradle 9 migration; standardising the nested daemon on
the same JDK avoids requiring an extra toolchain on dev machines and CI
runners).
Consumers that need a different JDK or Gradle version still override
explicitly. The inner build script is responsible for pinning the produced
bytecode level (`java { sourceCompatibility = JavaVersion.VERSION_1_8 }` or
similar) — Gradle adds `--release N` automatically when source/target differs
from the daemon JVM.
`JavaToolchainService` is now injected into the extension; this works in any
project where a `java*` (or related) plugin is applied. Smoke-test modules
already apply `gradle/java.gradle`, which applies `java`, so the convention
resolves on first read.
Public defaults exposed as `DEFAULT_NESTED_GRADLE_VERSION` and
`DEFAULT_NESTED_JAVA_VERSION` constants so the values are discoverable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chore(build-logic): use org.gradle.kotlin.dsl idioms in smoke-test plugin
Switch the plugin sources and unit tests over to the typed
`org.gradle.kotlin.dsl` extension functions where they replace
`::class.java` boilerplate:
- `tasks.register(name, Type::class.java) { … }` → `tasks.register<Type>(name) { … }`
- `tasks.withType(Type::class.java).configureEach { … }` → `tasks.withType<Type>().configureEach { … }`
- `extensions.create("name", Type::class.java)` → `extensions.create<Type>("name")`
- `extensions.getByType(Type::class.java)` → `extensions.getByType<Type>()`
- `extensions.findByName("name")` (followed by `isInstanceOf`) → `extensions.findByType<Type>()`
- `project.plugins.apply(Plugin::class.java)` → `project.apply<Plugin>()` (PluginAware)
- `objects.newInstance(Type::class.java)` → `objects.newInstance<Type>()`
Also drop the six `captured*` local variables in `SmokeTestAppExtension.application` —
inside `tasks.register<NestedGradleBuild>(taskName) { … }` the outer extension's
properties are now reached via `this@SmokeTestAppExtension.<prop>` directly.
No behavioural change; the 9 plugin tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chore(smoke-tests): switch spring-boot-2.7-webflux to the smoke-test plugin
This module already had a nested `application/` Gradle subproject built
via an `Exec` task that invoked the root `gradlew`. With the root build
moving to Gradle 9 (incompatible with Spring Boot plugin 2.x), the
nested build must pin its own Gradle version.
Swap the `Exec` task for the `smokeTestApp { application { … } }` DSL
from the `build-logic:smoke-test` plugin: Gradle 8.14.5 is pinned via
the Tooling API, the Java 8 toolchain is applied to the nested daemon,
and `dd-trace-api.jar` is forwarded via `projectJar('apiJar', …)`
(resolved through a `Configuration`, so no `evaluationDependsOn` is
needed).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merge branch 'master' into bdu/smoke-test-pattern-c-webflux
docs(smoke-tests): document nested-build settings.gradle config choices
Match the review feedback applied on #11408: expand the terse comments
in the spring-boot-2.7-webflux nested settings.gradle to explain the CI
Maven mirror proxies and the CI-only shared build cache (f6ec1f5 /
#982, b34ccbc).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
docs(smoke-tests): shorten Java 8 bytecode comment
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merge branch 'master' into bdu/smoke-test-pattern-c-webflux
Co-authored-by: brice.dutheil <brice.dutheil@datadoghq.com>
#11421) chore(build-logic): add smoke-test plugin for nested Gradle builds Adds a new included build `build-logic/` hosting a single subproject `smoke-test` that exposes the `dd-trace-java.smoke-test-app` plugin. The plugin contributes: - `NestedGradleBuild` task type that runs a nested Gradle build via the Gradle Tooling API. It 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>`, and redirects the nested `buildDir` via `-PappBuildDir=<path>` so outputs land under the outer project's build directory. - `smokeTestApp` project extension with an `application { ... }` block that registers the `NestedGradleBuild` task, wires it into every `Test` task via `dependsOn` + a `jvmArgumentProvider` for the produced artifact's system property. Consumers can also register `NestedGradleBuild` directly when they need more control; the plugin is a no-op until `application` or a manual registration is done. - `projectJar(name, project)` helper that forwards a sibling project's jar to the nested build through a resolvable `Configuration` (avoids `evaluationDependsOn` and the cross-project access ordering issues). The plugin is verified with JUnit 5 unit tests (`ProjectBuilder`) and end-to-end tests that drive the Tooling API path through the Gradle Test Kit with a temporary Kotlin-DSL test project. `build-logic/settings.gradle.kts` references the existing `gradle/libs.versions.toml` catalog (mirroring `buildSrc/`) so the plugin can use the same library coordinates as the rest of the repo. The Gradle libs Maven repository (`https://repo.gradle.org/gradle/libs-releases`, scoped to `org.gradle:`) is added to the root build's `pluginManagement` and to `gradle/repositories.gradle` so the Tooling API jar resolves. Smoke-test modules with Spring Boot plugin versions incompatible with Gradle 9 will use this plugin in follow-up PRs instead of a committed Gradle 8 wrapper. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> chore(build-logic): default smokeTestApp to JDK 21 daemon + Gradle 8.14.5 Set conventions on `smokeTestApp`: - `gradleVersion` defaults to `"8.14.5"` (Gradle 8 last release; pinned because Spring Boot plugin pre-3.5 calls `Configuration.getUploadTaskName()`, removed in Gradle 9). - `javaLauncher` defaults to a JDK 21 toolchain (the version the root build requires for its own Gradle 9 migration; standardising the nested daemon on the same JDK avoids requiring an extra toolchain on dev machines and CI runners). Consumers that need a different JDK or Gradle version still override explicitly. The inner build script is responsible for pinning the produced bytecode level (`java { sourceCompatibility = JavaVersion.VERSION_1_8 }` or similar) — Gradle adds `--release N` automatically when source/target differs from the daemon JVM. `JavaToolchainService` is now injected into the extension; this works in any project where a `java*` (or related) plugin is applied. Smoke-test modules already apply `gradle/java.gradle`, which applies `java`, so the convention resolves on first read. Public defaults exposed as `DEFAULT_NESTED_GRADLE_VERSION` and `DEFAULT_NESTED_JAVA_VERSION` constants so the values are discoverable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> chore(build-logic): use org.gradle.kotlin.dsl idioms in smoke-test plugin Switch the plugin sources and unit tests over to the typed `org.gradle.kotlin.dsl` extension functions where they replace `::class.java` boilerplate: - `tasks.register(name, Type::class.java) { … }` → `tasks.register<Type>(name) { … }` - `tasks.withType(Type::class.java).configureEach { … }` → `tasks.withType<Type>().configureEach { … }` - `extensions.create("name", Type::class.java)` → `extensions.create<Type>("name")` - `extensions.getByType(Type::class.java)` → `extensions.getByType<Type>()` - `extensions.findByName("name")` (followed by `isInstanceOf`) → `extensions.findByType<Type>()` - `project.plugins.apply(Plugin::class.java)` → `project.apply<Plugin>()` (PluginAware) - `objects.newInstance(Type::class.java)` → `objects.newInstance<Type>()` Also drop the six `captured*` local variables in `SmokeTestAppExtension.application` — inside `tasks.register<NestedGradleBuild>(taskName) { … }` the outer extension's properties are now reached via `this@SmokeTestAppExtension.<prop>` directly. No behavioural change; the 9 plugin tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> chore(smoke-tests): convert SB3 / quarkus / armeria / vertx to smoke-test plugin Drop-in conversion of ten more nested-build smoke tests to the `dd-trace-java.smoke-test-app` plugin (added in #11405). All ten previously used an `Exec` task that shelled out to a `gradlew` — either the root build's (now Gradle 9, incompatible with their plugin chain) or a committed inner wrapper. Spring Boot 3 / Gradle nested build, root-gradlew Exec: - `spring-boot-3.0-webflux` - `spring-boot-3.0-webmvc` - `spring-boot-3.3-webmvc` - `kafka-3` Non-Spring Gradle nested build, root-gradlew Exec: - `quarkus` (Quarkus 1.9.2 platform, Java 8) - `armeria-grpc` Inner Gradle wrapper (committed) → Tooling API: - `vertx-3.4`, `vertx-3.9`, `vertx-3.9-resteasy`, `vertx-4.2` The committed inner `gradlew` / `gradlew.bat` / `gradle/wrapper/` files are removed — the Tooling API pins the same Gradle 8.14.5 distribution the wrappers used. Each module's outer `build.gradle` collapses to a small `smokeTestApp { application { taskName / nestedTasks / artifactPath / sysProperty } projectJar(...) }` block. The daemon Gradle version + JDK 21 toolchain come from the plugin's conventions. Each inner `application/build.gradle` pins `sourceCompatibility` explicitly so JDK 21's javac cross-compiles to the right bytecode level (`--release`): Java 8 for `quarkus` and the vertx modules, Java 17 for the rest. `kafka-3` swaps its `toolchain.languageVersion` for `sourceCompatibility` to avoid pulling a separate JDK 17 toolchain on top of the daemon's JDK 21. Verified locally on Gradle 9.5.1: all ten nested builds produce their expected artifact; representative smoke tests (`spring-boot-3.0-webmvc`, `kafka-3`, `vertx-3.9`) pass with `-PskipFlakyTests=true`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> docs(smoke-tests): document nested-build settings.gradle config choices Match the review feedback applied on #11408: expand the terse comments on the nested settings.gradle files to explain the CI Maven mirror proxies and the CI-only shared build cache (f6ec1f5 / #982, b34ccbc), plus the Quarkus plugin version property forwarding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Merge branch 'master' into bdu/smoke-test-pattern-f-drop-in Remove unnecessary Quarkus smoke test launcher fix(smoke-tests): pin Quarkus 1.9.2 launcher back to JDK 11 The previous commit removed the explicit `javaLauncher` thinking it was unnecessary, but Quarkus 1.9.2 (Sep 2020) cannot run on JDK 21. With the launcher removed, the smoke-test plugin defaulted to JDK 21 and the Quarkus app process exited before opening its port, causing 8 initialization errors in QuarkusJBossLoggingSmokeTest / QuarkusSlf4jSmokeTest. Restore the launcher pinned to JDK 11 — within Quarkus 1.x's supported JDK range (8 / 11). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: devflow.devflow-routing-intake <devflow.devflow-routing-intake@kubernetes.us1.ddbuild.io>
What Does This Do
For 12 smoke-test modules whose Spring Boot Gradle plugin is incompatible with Gradle 9, this PR extracts the application source into a self-contained
application/Gradle subproject and switches the outer module to thesmokeTestApp { application { … } }DSL added in #11405.Modules converted (bootJar):
springboot-thymeleaf(Spring Boot 2.7.15, Java 8)springboot-freemarker(Spring Boot 2.7.15 plugin / 1.5.18 starter, Java 8)springboot-velocity(Spring Boot 2.7.15 plugin / 1.5.18 starter, Java 8)springboot-java-11(Spring Boot 2.7.15, Java 11; passesiast-util-11jar)springboot-java-17(Spring Boot 2.7.15, Java 17; passesiast-util-17jar)openfeature(Spring Boot 2.7.15, Java 11; passesfeature-flagging-apijar)kafka-2(Spring Boot 2.7.15, Java 8; passesiast-utiljar)apm-tracing-disabled(Spring Boot 2.7.15, Java 8; passesdd-trace-apijar)Modules converted (bootWar):
springboot-jpa(Spring Boot 2.6.0, Java 8; Lombok)springboot-tomcat-jsp(Spring Boot 2.7.15, Java 8; JSP webapp)springboot-jetty-jsp(Spring Boot 2.7.15, Java 8; JSP webapp)springboot-tomcat(Spring Boot 2.5.12, Java 8; Ivy Tomcat download + unzip)Tip
For each module the change is uniform:
git mv src/main/ application/src/main/application/settings.gradle+application/build.gradlecarrying the Spring Boot plugin + the module's existing dependencies.build.gradlerewritten to applydd-trace-java.smoke-test-appand configuresmokeTestApp { application { … } }(plusprojectJar(name, project)for the 5 modules that forward a sibling jar).Note
smokeTestApphas a convention of running Gradle 8.14.5, with a daemon running on Java 21, so it's not explicitly set. It's configurable if needed.Motivation
The Spring Boot Gradle plugin pre-3.5.0 calls
Configuration.getUploadTaskName(), removed in Gradle 9. These 12 modules block the root Gradle 9 migration.Mirrors the goal of PR #11379 "Pattern C" (12 modules, source extraction), but instead of committing 22 per-application
gradlewwrappers it uses the Gradle Tooling API via thedd-trace-java.smoke-test-appplugin (#11405). Net diff per module is smaller; nothing extra is committed to source control beyond the innerapplication/Gradle scripts.Additional Notes
kafka-2:spring-kafka-testis pinned to 2.8.11 in the outer test module (was previously resolved from the Spring Boot BOM, which no longer applies to the outer module).springboot-freemarker/springboot-velocity: theirXssControllerloads templates fromresources/main/templatesrelative to the test JVM working directory. After the source move, the processed resources land underbuild/application/resources/main/. Each affected outer build adds acopyAppResourcesCopy task that mirrors them tobuild/resources/main/so the runtime path resolves.jardependsOn this Copy task to avoid an implicit-output conflict.springboot-tomcat: the Ivy-downloaded Tomcat server (apache-tomcat-9.0.117) stays inside the nested build; the outer build forwards the unpack directory as a second system property viaadditionalSystemProperties.apm-tracing-disabled:ApmTracingDisabledSamplingSmoke{V04,V1}Testare already@Flakyand continue to be skipped in CI../gradlew :dd-smoke-tests:<module>:test -PskipFlakyTests=truefor each module.Contributor Checklist
type:and (comp:orinst:) labels in addition to any other useful labels🤖 Generated with Claude Code