From ca1f6e065602369514349779c19b1af8d3798dac Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Sun, 8 Nov 2026 00:33:29 +0100 Subject: [PATCH 1/4] build: make smoke test agent inputs reproducible Commit stamps and filesystem traversal order change the packaged agent even when its code and configuration are unchanged, invalidating smoke test results on fresh checkouts. Use runtime classpath normalisation for the agent input and track the project version explicitly. Keep classes, .classdata, manifests and indexes in the fingerprint. Track the presence of dd-java-agent.version separately because Gradle CI Visibility needs it to initialise. Keep the argument provider in the shared smoke-test build script and ignore other generated version resources without running packaging verification. Sort JMX metric configuration names before writing the packaged list so fresh checkouts produce identical resource bytes. Allow S3 cache entries up to 256 MiB so smoke application builds larger than the plugin's 50 MiB default can be stored. --- dd-java-agent/agent-jmxfetch/build.gradle | 2 ++ dd-smoke-tests/build.gradle | 28 +++++++++++++++++++++-- docs/gradle_build_cache.md | 13 +++++++---- settings.gradle.kts | 2 ++ 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/dd-java-agent/agent-jmxfetch/build.gradle b/dd-java-agent/agent-jmxfetch/build.gradle index bb1249350b0..3e9e6f8bbcf 100644 --- a/dd-java-agent/agent-jmxfetch/build.gradle +++ b/dd-java-agent/agent-jmxfetch/build.gradle @@ -67,6 +67,8 @@ abstract class CopyMetricConfigsTask extends DefaultTask { def configDirectoryPath = createConfigDirectory() def configPaths = Files.find(this.inputDirectory.toPath(), 10, this::checkMetricsFile) .map(p -> copyMetricsFile(configDirectoryPath, p)) + // Keep the packaged list independent of filesystem traversal order. + .sorted() .collect(Collectors.toList()) saveConfig(configDirectoryPath.parent, configPaths) } diff --git a/dd-smoke-tests/build.gradle b/dd-smoke-tests/build.gradle index fed2b5b5d1e..19dc8b32224 100644 --- a/dd-smoke-tests/build.gradle +++ b/dd-smoke-tests/build.gradle @@ -1,4 +1,5 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import java.util.jar.JarFile plugins { id 'dd-trace-java.module.smoke-test' @@ -38,6 +39,7 @@ allprojects { Project subProj -> def diagnosticsTaskRef = project(':dd-java-agent:instrumentation-testing').tasks.named('scopeDiagnosticsAgentJar', Jar) def agentArguments = subProj.objects.newInstance(SmokeAgentArguments) agentArguments.tracerJar.set(agentTaskRef.flatMap { it.archiveFile }) + agentArguments.tracerVersion.set(subProj.version.toString()) agentArguments.diagnosticsJar.set(diagnosticsTaskRef.flatMap { it.archiveFile }) jvmArgumentProviders.add(agentArguments) @@ -50,10 +52,24 @@ allprojects { Project subProj -> } abstract class SmokeAgentArguments implements CommandLineArgumentProvider { - @InputFile - @PathSensitive(PathSensitivity.NONE) + // Runtime classpath hashing tracks classes and resources: .classdata, manifests, instrumentation + // indexes, configuration files and native libraries. Changes to normalised contents invalidate tests. + @Classpath abstract RegularFileProperty getTracerJar() + // project.version is the base version (e.g. 1.69.0-SNAPSHOT); WriteVersionFile appends ~. + // Runtime-classpath normalisation excludes the complete *.version resources. + // Tracking the base version separately invalidates results on version changes, + // while changing only the commit stamp allows reuse when the other inputs match. + @Input + abstract Property getTracerVersion() + + // Gradle CI Visibility loads dd-java-agent.version, so its presence affects smoke results. + @Input + Provider> getNeededResourcePaths() { + tracerJar.map(existingResourcePaths('dd-java-agent.version')) + } + @InputFile @PathSensitive(PathSensitivity.NONE) abstract RegularFileProperty getDiagnosticsJar() @@ -65,4 +81,12 @@ abstract class SmokeAgentArguments implements CommandLineArgumentProvider { '-Ddatadog.smoketest.scopeDiagnostics.agent.path=' + diagnosticsJar.get().asFile.absolutePath ] } + + private static Transformer, RegularFile> existingResourcePaths(String... paths) { + return { RegularFile file -> + new JarFile(file.asFile).withCloseable { jar -> + paths.findAll { jar.getJarEntry(it) != null }.sort() + } + } as Transformer, RegularFile> + } } diff --git a/docs/gradle_build_cache.md b/docs/gradle_build_cache.md index 23682a2ffa6..7e5519e2430 100644 --- a/docs/gradle_build_cache.md +++ b/docs/gradle_build_cache.md @@ -84,17 +84,20 @@ Local runs diagnose inputs, but do not verify CI's S3 access. S3 misses can also mean HTTP 403 (access denied) or an entry larger than the plugin's `maximumCachedObjectLength`. Use `--info` to check the key and reason before assuming -an entry is missing. +an entry is missing. This build allows entries up to 256 MiB so smoke application builds +can be stored and restored. Check build logic, dependencies, JVM/toolchains, flags, platform, container digests, and generated files. Timestamps and absolute paths can cause unnecessary misses; missing inputs can cause incorrect hits. See Gradle's [cache debugging guide](https://docs.gradle.org/current/userguide/build_cache_debugging.html). -Smoke tests track the complete agent JAR through `SmokeAgentArguments.tracerJar` (`@InputFile`). -Its generated `.version` files contain the commit hash, so a new commit can cause smoke-test -misses even with identical sources. Compilation may still hit the cache. Rerun the same commit -with matching inputs to measure smoke-test reuse. +Smoke tests fingerprint the agent JAR through `SmokeAgentArguments.tracerJar` (`@Classpath`). +Runtime-classpath normalisation excludes generated `.version` resources; the project version +is tracked separately. `neededResourcePaths` tracks `dd-java-agent.version`, which Gradle +CI Visibility requires to initialise. Its presence remains an input while its stamp is +excluded. Commit-only changes can reuse matching results; classes, `.classdata` and other +resources remain in the fingerprint. ## Inspect a cache entry diff --git a/settings.gradle.kts b/settings.gradle.kts index cd24f069740..0470313a5b6 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -94,6 +94,8 @@ if (isCI.isPresent) { isPush = true lookupDefaultAwsCredentials = true isReducedRedundancy = false + // Smoke application build entries exceed the plugin's 50 MiB default limit. + maximumCachedObjectLength = 256L * 1024 * 1024 } } } From 5424d05259adccf101097d94c19653a45dc498c3 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Sun, 8 Nov 2026 00:33:56 +0100 Subject: [PATCH 2/4] build: normalise forwarded smoke-test JAR inputs Use one projectJar API with classpath fingerprints for JVM and native application dependencies, including non-default artifact configurations. Ignore ZIP metadata and the existing version-resource exclusions while tracking the producing project's version separately. Cached JVM applications and native executables may retain earlier embedded agent and API commit stamps when only excluded metadata changes. Track needed resource names separately so adding or removing the agent version resource also invalidates native builds. Keep packaging verification in its existing flow. Qualify API-property lookups inside dependency blocks so the JVM consumers select the forwarded project JAR instead of a fallback. Cover cache restoration, configuration-cache reuse, project versions, class and classdata changes, required resources and ZIP entry order for default and shadow JARs. Re-snapshot externally rewritten test JARs. Document input annotations, normalisation and cache fingerprint comparisons in the build-cache guide. Explain classpath normalisation, base versions and required resource presence beside the nested JAR inputs. --- .../smoketest/NestedBuildProjectJar.kt | 39 +++- .../buildlogic/smoketest/NestedGradleBuild.kt | 7 +- .../smoketest/SmokeTestAppExtension.kt | 58 +++--- .../smoketest/SmokeTestAppEndToEndTest.kt | 133 ++++++++++++- .../armeria-grpc/application/build.gradle | 2 +- .../quarkus/application/build.gradle | 2 +- docs/gradle_build_cache.md | 174 ++++++++++++++++-- 7 files changed, 347 insertions(+), 68 deletions(-) diff --git a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedBuildProjectJar.kt b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedBuildProjectJar.kt index 503f78c47b4..4fb6cb373ff 100644 --- a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedBuildProjectJar.kt +++ b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedBuildProjectJar.kt @@ -1,24 +1,53 @@ package datadog.buildlogic.smoketest +import org.gradle.api.Transformer +import org.gradle.api.file.RegularFile import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity +import java.util.jar.JarFile /** * A jar produced by the root build that needs to be forwarded into a [NestedGradleBuild]. * * At execution time the task adds `-P${propertyName}=` to the nested * Gradle invocation, so the inner build script can pick it up via `findProperty(...)`. + * + * Cached JVM and native fixtures can retain earlier embedded commit stamps. */ abstract class NestedBuildProjectJar { @get:Input abstract val propertyName: Property - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) + /** + * Runtime classpath hashing tracks classes and resources: .classdata, manifests, instrumentation + * indexes, configuration files and native libraries. Changes to normalised contents invalidate + * application builds. + */ + @get:Classpath abstract val file: RegularFileProperty + + /** + * `project.version` is the base version (e.g. `1.69.0-SNAPSHOT`); `WriteVersionFile` appends `~`. + * Runtime-classpath normalisation excludes the complete `*.version` resources. + * Tracking the base version separately invalidates application builds on version changes, + * while changing only the commit stamp allows reuse when the other inputs match. + */ + @get:Input + abstract val version: Property + + /** Gradle CI Visibility loads `dd-java-agent.version`, so its presence affects smoke results. */ + @get:Input + val neededResourcePaths: Provider> + get() = file.map(existingResourcePaths("dd-java-agent.version")) + + private fun existingResourcePaths(vararg paths: String): Transformer, RegularFile> = + Transformer { file -> + JarFile(file.asFile).use { jar -> + paths.filter { jar.getJarEntry(it)?.isDirectory == false }.sorted() + } + } } diff --git a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt index 49fc7bcbb01..b65928d6597 100644 --- a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt +++ b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt @@ -163,17 +163,18 @@ abstract class NestedGradleBuild @Inject constructor( @get:OutputDirectory abstract val applicationBuildDir: DirectoryProperty - /** Forward a root-build jar as `-P=` into the nested build. */ - fun projectJar(name: String, file: Provider) { + /** Forward a JAR with runtime-classpath normalisation and an explicit base [version]. */ + fun projectJar(name: String, file: Provider, version: Provider) { projectJars.add( objects.newInstance().apply { propertyName.set(name) this.file.set(file) + this.version.set(version) }, ) } - /** Configure additional aspects of the nested build via a typed action. */ + /** Configure a normalised JAR input, including its base version, via a typed action. */ fun projectJar(action: Action) { projectJars.add( objects.newInstance().also(action::execute), diff --git a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppExtension.kt b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppExtension.kt index da6a7c1f0a3..589baca8a0c 100644 --- a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppExtension.kt +++ b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppExtension.kt @@ -213,31 +213,31 @@ abstract class SmokeTestAppExtension @Inject constructor( } /** - * Forward the default `jar` artifact from [sourceProject] into the nested build as - * `-P=`. The jar is consumed via a resolvable [Configuration], - * which both establishes the correct task dependency and lets Gradle resolve the artifact - * lazily — no `evaluationDependsOn` is needed. + * Forward a JAR from [sourceProject] as `-P=`. + * [configuration] selects an outgoing artifact configuration, such as `shadow`; + * the default artifact is used when it is omitted. Resolution is lazy and carries + * the producing task dependency. + * + * Fingerprints use this project's runtime-classpath normalisation and track the + * producing project's version separately. Classes, `.classdata` and other tracked + * resources remain inputs; ZIP metadata and configured resource exclusions are ignored. + * Cached JVM applications and native executables can retain earlier embedded agent + * and API commit stamps when only excluded version metadata changes. */ - fun projectJar(propertyName: String, sourceProject: Project) { - val cfg = createExtraJarConfiguration(propertyName) - project.dependencies.add(cfg.name, sourceProject) - addProjectJarFromConfiguration(propertyName, cfg) - } - - /** - * Forward a non-default artifact configuration from [sourceProject]. Use this when the - * upstream project exposes its build output under a configuration other than the default - * (e.g. `shadowJar`). - */ - fun projectJar(propertyName: String, sourceProject: Project, configuration: String) { + @JvmOverloads + fun projectJar(propertyName: String, sourceProject: Project, configuration: String? = null) { val cfg = createExtraJarConfiguration(propertyName) project.dependencies.add( cfg.name, - project.dependencies.project( + if (configuration == null) sourceProject else project.dependencies.project( mapOf("path" to sourceProject.path, "configuration" to configuration), ), ) - addProjectJarFromConfiguration(propertyName, cfg) + projectJar( + propertyName, + project.layout.file(cfg.elements.map { files -> files.single().asFile }), + sourceProject.provider { sourceProject.version.toString() }, + ) } private fun createExtraJarConfiguration(propertyName: String): Configuration { @@ -253,29 +253,15 @@ abstract class SmokeTestAppExtension @Inject constructor( /** * Lower-level overload for the rare case where the caller already has a provider of the - * file. The caller is responsible for the upstream task dependency. + * file and its base [version]. Uses the same normalisation as the project overload; + * the caller is responsible for the upstream task dependency. */ - fun projectJar(propertyName: String, file: Provider) { + fun projectJar(propertyName: String, file: Provider, version: Provider) { projectJars.add( project.objects.newInstance().apply { this.propertyName.set(propertyName) this.file.set(file) - }, - ) - } - - private fun addProjectJarFromConfiguration(propertyName: String, cfg: Configuration) { - projectJars.add( - project.objects.newInstance().apply { - this.propertyName.set(propertyName) - // Configuration.elements yields a Provider that carries the producing task dependency, - // so wiring it into the task's @InputFile both tracks file contents and arranges build - // order. - this.file.set( - cfg.elements.map { files -> - project.objects.fileProperty().fileValue(files.single().asFile).get() - }, - ) + this.version.set(version) }, ) } diff --git a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt index 01ae03fe534..01b0ed89f74 100644 --- a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt +++ b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt @@ -14,6 +14,9 @@ import org.tabletest.junit.TableTest import java.io.File import java.nio.file.Files import java.nio.file.Path +import java.util.jar.JarEntry +import java.util.jar.JarFile +import java.util.jar.JarOutputStream /** * End-to-end tests that drive the plugin through the Gradle Test Kit and a temporary, @@ -66,6 +69,128 @@ class SmokeTestAppEndToEndTest { assertThat(applicationOutput("libs/sample.jar")).exists() } + @TableTest( + "scenario | configuration | change | expected ", + "commit stamp ignored | default | stamp | FROM_CACHE ", + "ZIP timestamps ignored | default | zip | FROM_CACHE ", + "ZIP entry order ignored | default | order | FROM_CACHE ", + "project version tracked | default | version | SUCCESS ", + "class contents tracked | default | class | SUCCESS ", + "classdata tracked | default | classdata | SUCCESS ", + "other resources tracked | default | resource | SUCCESS ", + "agent version added | default | added | SUCCESS ", + "agent version removed | default | removed | SUCCESS ", + "other version paths ignored | default | paths | FROM_CACHE ", + "shadow commit stamp ignored | shadow | stamp | FROM_CACHE ", + "shadow ZIP timestamps ignored | shadow | zip | FROM_CACHE ", + "shadow ZIP entry order ignored | shadow | order | FROM_CACHE ", + "shadow project version tracked | shadow | version | SUCCESS ", + "shadow class contents tracked | shadow | class | SUCCESS ", + "shadow classdata tracked | shadow | classdata | SUCCESS ", + "shadow other resources tracked | shadow | resource | SUCCESS ", + "shadow agent version added | shadow | added | SUCCESS ", + "shadow agent version removed | shadow | removed | SUCCESS ", + "shadow other versions ignored | shadow | paths | FROM_CACHE ", + ) + fun `project JAR fingerprints ignore metadata and track source changes`( + configuration: String, + change: String, + expected: TaskOutcome, + ) { + writeOuterSettings(withLocalBuildCache = true) + outerSettings.appendText("\ninclude(\":api\")\n") + val apiDirectory = projectDir.resolve("api").toFile().apply { mkdirs() } + File(apiDirectory, "build.gradle.kts").writeText( + """ + plugins { base } + version = providers.gradleProperty("apiVersion").getOrElse("1.0") + val prepareJar = tasks.register("prepareJar") { + from("input.jar") + into(layout.buildDirectory.dir("libs")) + } + val outgoing = configurations.${if (configuration == "default") "named(\"default\")" else "create(\"shadow\")"} { + isCanBeConsumed = true + isCanBeResolved = false + } + artifacts.add(outgoing.name, layout.buildDirectory.file("libs/input.jar")) { + builtBy(prepareJar) + } + """.trimIndent(), + ) + writeSmokeTestAppBuild( + """ + ${smokeTestGradleApplication("packageApp", "embedded-api.jar", "api.path")} + projectJar("apiJar", project(":api")${if (configuration == "default") "" else ", \"shadow\""}) + """, + extraImports = "import datadog.buildlogic.smoketest.NestedGradleBuild", + extraPreamble = """ + normalization.runtimeClasspath.ignore("**/*.version") + tasks.withType().configureEach { + actions.clear() + val inputJar = projectJars.flatMap { it.single().file } + val target = applicationBuildDir.file("embedded-api.jar") + doLast { + target.get().asFile.apply { + parentFile.mkdirs() + inputJar.get().asFile.copyTo(this, overwrite = true) + } + } + } + """, + ) + + fun writeApiJar(changed: Boolean) { + val entries = mutableMapOf( + "api.version" to if (changed && change == "stamp") "1.0~next" else "1.0~initial", + "example/Api.class" to if (changed && change == "class") "changed class" else "class", + "example/Agent.classdata" to if (changed && change == "classdata") "changed classdata" else "classdata", + "config.txt" to if (changed && change == "resource") "changed resource" else "resource", + ) + if (changed && change == "paths") { + entries["optional.version"] = "1.0~initial" + } + if ((changed && change == "added") || (!changed && change == "removed")) { + entries["dd-java-agent.version"] = "1.0~initial" + } + JarOutputStream(File(apiDirectory, "input.jar").outputStream()).use { jar -> + val orderedEntries = if (changed && change == "order") entries.toList().reversed() else entries.toList() + orderedEntries.forEach { (name, contents) -> + jar.putNextEntry(JarEntry(name).apply { + time = if (changed && change == "zip") 1700000000000L else 1000000000000L + }) + jar.write(contents.toByteArray(Charsets.UTF_8)) + jar.closeEntry() + } + } + } + + writeApiJar(changed = false) + // Re-snapshot the JAR rewritten outside Gradle between runs. + val first = runner("packageApp", "--build-cache", "--configuration-cache", "--no-watch-fs", "-PapiVersion=1.0").build() + assertThat(first.task(":api:prepareJar")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(first.task(":packageApp")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + + applicationBuildDir.deleteRecursively() + writeApiJar(changed = true) + val second = runner( + "packageApp", "--build-cache", "--configuration-cache", "--no-watch-fs", + "-PapiVersion=${if (change == "version") "2.0" else "1.0"}", + ).build() + if (change != "version") { + assertThat(second.task(":api:prepareJar")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + assertThat(second.task(":packageApp")?.outcome).isEqualTo(expected) + if (change != "version") { + assertThat(second.output).contains("Reusing configuration cache.") + } + JarFile(applicationOutput("embedded-api.jar")).use { jar -> + val stamp = jar.getInputStream(jar.getJarEntry("api.version")).bufferedReader().use { it.readText() } + assertThat(stamp).isEqualTo("1.0~initial") + assertThat(jar.getJarEntry("dd-java-agent.version") != null).isEqualTo(change == "added") + assertThat(jar.getJarEntry("optional.version")).isNull() + } + } + @Test fun `nested Maven build produces the configured artifact`() { writeOuterSettings() @@ -373,7 +498,7 @@ class SmokeTestAppEndToEndTest { fun `nested build receives native app environment and provider backed file inputs`() { writeOuterSettings() val graalvmHome = projectDir.resolve("test-graalvm").toFile() - File(projectDir.toFile(), "agent.jar").writeText("agent") + JarOutputStream(File(projectDir.toFile(), "agent.jar").outputStream()).use { } writeSmokeTestAppBuild( """ ${smokeTestGradleApplication( @@ -385,7 +510,11 @@ class SmokeTestAppEndToEndTest { environment.put("GRAALVM_HOME", providers.provider { layout.projectDirectory.dir("test-graalvm").asFile.absolutePath }) """, )} - projectJar("agentPath", providers.provider { layout.projectDirectory.file("agent.jar") }) + projectJar( + "agentPath", + providers.provider { layout.projectDirectory.file("agent.jar") }, + providers.provider { "1.0" }, + ) """, ) writeInnerSettings() diff --git a/dd-smoke-tests/armeria-grpc/application/build.gradle b/dd-smoke-tests/armeria-grpc/application/build.gradle index 7800b4519a1..a16a2601ef9 100644 --- a/dd-smoke-tests/armeria-grpc/application/build.gradle +++ b/dd-smoke-tests/armeria-grpc/application/build.gradle @@ -61,7 +61,7 @@ dependencies { runtimeOnly 'ch.qos.logback:logback-classic:1.4.7' runtimeOnly 'org.slf4j:log4j-over-slf4j:1.7.36' - if (hasProperty('apiJar')) { + if (project.hasProperty('apiJar')) { implementation files(property('apiJar')) } else { implementation "com.datadoghq:dd-trace-api:+" diff --git a/dd-smoke-tests/quarkus/application/build.gradle b/dd-smoke-tests/quarkus/application/build.gradle index 7fa5badaf5e..bea67fa528f 100644 --- a/dd-smoke-tests/quarkus/application/build.gradle +++ b/dd-smoke-tests/quarkus/application/build.gradle @@ -23,7 +23,7 @@ java { dependencies { implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}") implementation 'io.quarkus:quarkus-resteasy' - if (hasProperty('apiJar')) { + if (project.hasProperty('apiJar')) { implementation files(property('apiJar')) } else { implementation "com.datadoghq:dd-trace-api:0.68.0" diff --git a/docs/gradle_build_cache.md b/docs/gradle_build_cache.md index 7e5519e2430..f819196e938 100644 --- a/docs/gradle_build_cache.md +++ b/docs/gradle_build_cache.md @@ -70,17 +70,9 @@ If no summary appears, try `--info` and check cache and statistics settings. | Native smoke-test failures | Use `SKIP_BUILD_CACHE=true` to rebuild the executable in the failing job. Check that task inputs track changes to the toolchain and builder image. | | Hits without faster CI | Transfers, configuration time, tasks that still execute, and the pipeline's critical path. | -Compare task inputs in [Build Scans](how_to_work_with_gradle.md#build-scans-develocity). -Muzzle jobs disable scans; use logs instead. For detailed fingerprints: - -```shell -./gradlew :dd-trace-api:clean :dd-trace-api:test \ - --build-cache --info -Dorg.gradle.caching.debug=true -``` - -Replace the module/task as needed. Run twice and compare keys and input hashes. -Cleaning outputs allows restoration; omit `--rerun-tasks` when checking hits. -Local runs diagnose inputs, but do not verify CI's S3 access. +Compare task inputs in [Build Scans](how_to_work_with_gradle.md#build-scans-develocity) +or [compare their fingerprints in logs](#compare-fingerprints-in-logs). +Muzzle jobs disable scans; use logs instead. S3 misses can also mean HTTP 403 (access denied) or an entry larger than the plugin's `maximumCachedObjectLength`. Use `--info` to check the key and reason before assuming @@ -89,15 +81,157 @@ can be stored and restored. Check build logic, dependencies, JVM/toolchains, flags, platform, container digests, and generated files. Timestamps and absolute paths can cause unnecessary misses; -missing inputs can cause incorrect hits. See Gradle's -[cache debugging guide](https://docs.gradle.org/current/userguide/build_cache_debugging.html). - -Smoke tests fingerprint the agent JAR through `SmokeAgentArguments.tracerJar` (`@Classpath`). -Runtime-classpath normalisation excludes generated `.version` resources; the project version -is tracked separately. `neededResourcePaths` tracks `dd-java-agent.version`, which Gradle -CI Visibility requires to initialise. Its presence remains an input while its stamp is -excluded. Commit-only changes can reuse matching results; classes, `.classdata` and other -resources remain in the fingerprint. +missing inputs can cause incorrect hits. + +## Choose input fingerprints + +Choose the input declaration according to what the task consumes. A file's extension alone +does not determine its fingerprint: a JAR can be an exact archive or a runtime classpath. + +| Declaration | Use when | Changes that invalidate the input | +| ---------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| `@InputFile` / `@InputFiles` | Exact file contents matter, such as a checksum, signed archive or configuration file. | File bytes and the paths selected by `@PathSensitive`. ZIP metadata is part of the bytes. | +| `@Classpath` | The task executes or inspects JVM classes and resources, including a Java agent. | Normalised class and resource contents, and classpath entry order. JAR names, locations, ZIP timestamps and ZIP entry order are ignored. | +| `@CompileClasspath` | Only the Java API visible to compilation matters. | API changes. Method bodies, private members and resources are ignored. | +| `@Input` | A value affects execution, such as a version, flag or immutable container digest. | The value changes. | + +In a custom task or nested input object, declare these properties on their getters: + +```kotlin +@get:InputFile +@get:PathSensitive(PathSensitivity.NONE) +abstract val distributionArchive: RegularFileProperty + +@get:Classpath +abstract val tracerJar: RegularFileProperty + +@get:Input +abstract val tracerVersion: Property +``` + +`PathSensitivity.NONE` removes paths from the fingerprint while preserving file contents. +Use `RELATIVE` for a source tree whose internal paths matter. The default `ABSOLUTE` includes +the checkout location and prevents reuse across checkouts. `@Classpath` already defines its +path handling; use it without `@PathSensitive`. A task that embeds absolute paths in its +outputs also needs reproducible outputs before its cache can be shared. + +Use `@Classpath` for the smoke-test agent. It fingerprints `.classdata` as resources, so +changes to renamed agent classes still invalidate results. `@CompileClasspath` would ignore +those resources and implementation changes. See Gradle's +[`Classpath`](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/Classpath.html), +[`CompileClasspath`](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/CompileClasspath.html) +and [path sensitivity](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/PathSensitivity.html). + +### Normalise runtime inputs + +Normalisation defines which input differences can reuse the same cached outputs. It changes +the fingerprint; the task still receives the original file. Configure runtime normalisation +in the consuming project. This build applies the following rule to all projects: + +```kotlin +normalization { + runtimeClasspath { + ignore("**/*.version") + } +} +``` + +This excludes complete matching resources, including their presence and contents, from +`@Classpath` fingerprints. It does not affect `@InputFile` fingerprints. Keep exclusions +narrow and track any excluded information that still affects execution separately. +For a `.properties` resource, Gradle also supports +[ignoring individual properties](https://docs.gradle.org/current/javadoc/org/gradle/normalization/RuntimeClasspathNormalization.html) +instead of excluding the whole file. + +`SmokeAgentArguments.tracerVersion` tracks `project.version`, for example `1.69.0-SNAPSHOT`. +`WriteVersionFile` appends `~` when generating `.version` resources. Changing only the +SHA leaves both the normalised JAR and the explicit version input unchanged. Changing the +base version invalidates results even when classes are unchanged. `-SNAPSHOT` has no special +treatment in the fingerprint. + +Nested JVM and native application builds use the same normalisation with +`smokeTestApp.projectJar('apiJar', project(':dd-trace-api'))`. +The producing project's version is tracked separately, including for non-default artifacts +such as `projectJar('agentJar', project(':dd-java-agent'), 'shadow')`. +Cached application artifacts and native executables can retain earlier embedded agent +and API commit stamps when only excluded version metadata changes. +Use raw file inputs when cached artifacts must contain the current stamp. + +### Track excluded resource presence + +Resource presence can affect smoke-test results even when its contents are excluded. The +Gradle CI Visibility smoke tests load +[`CiVisibilityGradleListener`](../dd-java-agent/instrumentation/gradle/gradle-8.3/src/main/groovy/datadog/trace/instrumentation/gradle/CiVisibilityGradleListener.java), +which reads `dd-java-agent.version` during class initialisation. Removing that resource +can break the listener even when the agent's classes are unchanged. +`SmokeAgentArguments` and `NestedBuildProjectJar` each expose an +`neededResourcePaths` input derived lazily from their JAR file. It records the names of +resources required by the smoke tests, currently only `dd-java-agent.version`. Adding or +removing that resource changes the list and invalidates results. Changing its stamp leaves +the list and the normalised classpath unchanged. Other excluded `.version` resources have +no separate presence input. + +This is input fingerprinting and does not execute packaging checks. `verifyAgentJarContents` +stays in the agent's verification flow. Smoke tests depend on the agent artifact and declare +the inputs they consume; they do not look up a producer's verification task. When another +project needs an additional artifact, publish it through a consumable configuration, as +described in Gradle's [guide to sharing outputs between projects](https://docs.gradle.org/current/userguide/how_to_share_outputs_between_projects.html). + +The excluded stamp contents are intentionally outside the smoke-test cache key. A restored +test result does not establish that version metadata was validated for the current commit. + +## Compare fingerprints in logs + +Capture the same task on both sides of the change with detailed cache logging: + +```shell +./gradlew :dd-smoke-tests:quarkus:clean :dd-smoke-tests:quarkus:test \ + --build-cache --info --console=plain -Dorg.gradle.caching.debug=true \ + > before.log 2>&1 +``` + +Repeat with `after.log` after the change. Replace the task as needed and keep the JVM, +dependencies and flags comparable. Cleaning outputs allows restoration; omit `--rerun-tasks` +when checking hits. Local runs diagnose inputs, but do not verify CI's S3 access. + +Locate the task's block and compare these lines. The following is a shortened example; +property prefixes and hashes vary by task: + +```text +Appending implementation to build cache key: @ +Appending input value fingerprint for '...tracerVersion' to build cache key: +Appending input value fingerprint for '...neededResourcePaths' to build cache key: +Appending input file fingerprints for '...tracerJar' to build cache key: - CLASSPATH{...} +Appending output property name to build cache key: +Build cache key for task ':dd-smoke-tests:quarkus:test' is +``` + +```shell +rg -n --max-columns 300 --max-columns-preview \ + 'Build cache key|Appending .*implementation|Appending input|Appending output|Caching disabled|not up-to-date' \ + before.log after.log +``` + +Compare implementation and action hashes first: Gradle, build logic and plugin changes can +invalidate tasks even when input files match. Then compare each named value and file +fingerprint. Within a changed file property, compare normalised paths and individual file +hashes. `ABSOLUTE_PATH` can reveal checkout-path sensitivity; `CLASSPATH` identifies runtime +normalisation. An absolute path printed for locating a file does not by itself mean the path +contributes to the fingerprint. + +If `tracerVersion` matches but `tracerJar` differs, inspect the packaged classes and tracked +resources. ZIP timestamps are already ignored for `@Classpath`. A text resource containing +the same filenames in a different order still changes its fingerprint. This happened with +JMXFetch's `metricconfigs.txt`; sorting the names before writing the file fixed the cause. +Compare archive entries and their contents rather than only the whole-file checksum. + +`No history is available` explains a local up-to-date miss, not a failed cache lookup. +`Caching disabled for task` gives a reason that must be resolved before expecting cache +restoration. When the final keys match but restoration still fails, check the namespace, +permissions, entry-size limit and cache read settings, and whether the producer stored the +entry. Start with the earliest unexpected miss in the dependency chain: a rebuilt fixture +can change downstream test inputs. +See Gradle's [cache debugging guide](https://docs.gradle.org/current/userguide/build_cache_debugging.html). ## Inspect a cache entry From 1191ec829225ec5cfd3d35c9cc61dc3ce4bf5590 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Sun, 8 Nov 2026 00:34:37 +0100 Subject: [PATCH 3/4] build: make native smoke test executables portable Use a compatibility CPU target for the Quarkus and Spring Boot native fixtures so cached executables can run on other CI hosts of the same OS and architecture. Document why the S3 prefix does not isolate CPU features. Link the GraalVM guidance and record stronger targets as candidates requiring guarantees across eligible build and execution hosts. Resolve forwarded API JAR properties on the project inside dependency blocks so both native fixtures consume the supplied project JAR. --- dd-smoke-tests/quarkus-native/application/build.gradle | 9 +++++++-- .../spring-boot-3.0-native/application/build.gradle | 8 +++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/dd-smoke-tests/quarkus-native/application/build.gradle b/dd-smoke-tests/quarkus-native/application/build.gradle index 65beb08e810..18bff4374d2 100644 --- a/dd-smoke-tests/quarkus-native/application/build.gradle +++ b/dd-smoke-tests/quarkus-native/application/build.gradle @@ -22,7 +22,7 @@ def ciBuildCpuCount = providers.environmentVariable("KUBERNETES_CPU_REQUEST").ge dependencies { implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}") implementation 'io.quarkus:quarkus-resteasy' - if (hasProperty('apiJar')) { + if (project.hasProperty('apiJar')) { implementation files(property('apiJar')) } else { implementation "com.datadoghq:dd-trace-api:1.38.1" @@ -44,7 +44,12 @@ if (hasProperty('agentJar')) { "-J-javaagent:${agentJar}", "-J-Ddatadog.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd'T'HH:mm:ss.SSS'Z [dd.trace]'", "-J-Ddd.profiling.enabled=true", - "-march=native", + // The S3 prefix separates OS/architecture, but not CPU features. Use a common baseline + // so cached executables can run on other CI hosts. + // x86-64-v3 (AMD64) and armv8.1-a (AArch64) are candidates once all build and execution + // hosts of each architecture are guaranteed to support the corresponding CPU features. + // https://www.graalvm.org/latest/reference-manual/native-image/optimizations-and-performance/#optimizing-for-specific-machines + "-march=compatibility", ] if (isCI) { nativeBuildArgs.add("-H:NumberOfThreads=$ciBuildCpuCount") diff --git a/dd-smoke-tests/spring-boot-3.0-native/application/build.gradle b/dd-smoke-tests/spring-boot-3.0-native/application/build.gradle index 08545cf1e16..36ed50638f6 100644 --- a/dd-smoke-tests/spring-boot-3.0-native/application/build.gradle +++ b/dd-smoke-tests/spring-boot-3.0-native/application/build.gradle @@ -30,7 +30,7 @@ tasks.withType(JavaCompile).configureEach { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' - if (hasProperty('apiJar')) { + if (project.hasProperty('apiJar')) { implementation files(property('apiJar')) } else { implementation "com.datadoghq:dd-trace-api:1.2.0" @@ -44,6 +44,12 @@ if (hasProperty('agentPath')) { main { // quick build mode, enough for smoke test buildArgs.add("-Ob") + // The S3 prefix separates OS/architecture, but not CPU features. Use a common baseline + // so cached executables can run on other CI hosts. + // x86-64-v3 (AMD64) and armv8.1-a (AArch64) are candidates once all build and execution + // hosts of each architecture are guaranteed to support the corresponding CPU features. + // https://www.graalvm.org/latest/reference-manual/native-image/optimizations-and-performance/#optimizing-for-specific-machines + buildArgs.add("-march=compatibility") buildArgs.add("-J-javaagent:$agentPath") buildArgs.add("-J-Dnet.bytebuddy.safe=false") if (withProfiler && property('profiler') == 'true') { From f7be66ee36fc6e82a79efd00e3df0ca3f12db47e Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Sun, 8 Nov 2026 00:34:30 +0100 Subject: [PATCH 4/4] build: remove unused smoke-test project JAR inputs Remove eleven API JAR declarations and Kafka's unused application IAST helper JAR. Drop the matching nested dependencies and obsolete lockfile configuration names so unrelated JAR changes no longer rebuild fixtures. Keep the smoke-test harness dependencies, the WildFly WAR's published API, and the project JARs consumed by JVM and native applications. --- .../apm-tracing-disabled/application/build.gradle | 10 ---------- dd-smoke-tests/apm-tracing-disabled/build.gradle | 1 - dd-smoke-tests/apm-tracing-disabled/gradle.lockfile | 2 +- dd-smoke-tests/kafka-2/application/build.gradle | 10 ---------- dd-smoke-tests/kafka-2/build.gradle | 1 - dd-smoke-tests/kafka-2/gradle.lockfile | 2 +- dd-smoke-tests/rum/wildfly-15/build.gradle | 4 ---- .../spring-boot-2.7-webflux/application/build.gradle | 6 ------ dd-smoke-tests/spring-boot-2.7-webflux/build.gradle | 1 - dd-smoke-tests/spring-boot-2.7-webflux/gradle.lockfile | 2 +- .../spring-boot-3.0-webflux/application/build.gradle | 6 ------ dd-smoke-tests/spring-boot-3.0-webflux/build.gradle | 1 - dd-smoke-tests/spring-boot-3.0-webflux/gradle.lockfile | 2 +- .../spring-boot-3.0-webmvc/application/build.gradle | 7 ------- dd-smoke-tests/spring-boot-3.0-webmvc/build.gradle | 1 - dd-smoke-tests/spring-boot-3.0-webmvc/gradle.lockfile | 2 +- .../spring-boot-3.3-webmvc/application/build.gradle | 7 ------- dd-smoke-tests/spring-boot-3.3-webmvc/build.gradle | 1 - dd-smoke-tests/spring-boot-3.3-webmvc/gradle.lockfile | 2 +- dd-smoke-tests/vertx-3.4/build.gradle | 1 - dd-smoke-tests/vertx-3.4/gradle.lockfile | 2 +- dd-smoke-tests/vertx-3.9-resteasy/build.gradle | 1 - dd-smoke-tests/vertx-3.9-resteasy/gradle.lockfile | 2 +- dd-smoke-tests/vertx-3.9/build.gradle | 1 - dd-smoke-tests/vertx-3.9/gradle.lockfile | 2 +- dd-smoke-tests/vertx-4.2/build.gradle | 1 - dd-smoke-tests/vertx-4.2/gradle.lockfile | 2 +- dd-smoke-tests/wildfly/build.gradle | 4 ---- dd-smoke-tests/wildfly/spring-ear/build.gradle | 6 ------ 29 files changed, 10 insertions(+), 80 deletions(-) diff --git a/dd-smoke-tests/apm-tracing-disabled/application/build.gradle b/dd-smoke-tests/apm-tracing-disabled/application/build.gradle index cac44f5c2dd..c5c53aa544d 100644 --- a/dd-smoke-tests/apm-tracing-disabled/application/build.gradle +++ b/dd-smoke-tests/apm-tracing-disabled/application/build.gradle @@ -23,16 +23,6 @@ java { sourceCompatibility = '1.8' } -if (hasProperty('apiJar')) { - dependencies { - implementation files(property('apiJar')) - } -} else { - dependencies { - implementation "com.datadoghq:dd-trace-api:+" - } -} - dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' // OpenTracing 0.32.0 is the last release and is intentionally pinned: this smoke test diff --git a/dd-smoke-tests/apm-tracing-disabled/build.gradle b/dd-smoke-tests/apm-tracing-disabled/build.gradle index 70cfa763036..12e76629b11 100644 --- a/dd-smoke-tests/apm-tracing-disabled/build.gradle +++ b/dd-smoke-tests/apm-tracing-disabled/build.gradle @@ -12,7 +12,6 @@ smokeTestApp { artifactPath = 'libs/apm-tracing-disabled-smoketest.jar' sysProperty = 'datadog.smoketest.springboot.shadowJar.path' } - projectJar('apiJar', project(':dd-trace-api')) } dependencies { diff --git a/dd-smoke-tests/apm-tracing-disabled/gradle.lockfile b/dd-smoke-tests/apm-tracing-disabled/gradle.lockfile index c2deddd2dcf..7ef29f459b4 100644 --- a/dd-smoke-tests/apm-tracing-disabled/gradle.lockfile +++ b/dd-smoke-tests/apm-tracing-disabled/gradle.lockfile @@ -128,4 +128,4 @@ org.tabletest:tabletest-junit:1.2.2=testCompileClasspath,testRuntimeClasspath org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.21.4=testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=annotationProcessor,runtimeClasspath,smokeTestAppExtraJarApiJar,spotbugsPlugins,testAnnotationProcessor,testFixturesAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath +empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor,testFixturesAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/dd-smoke-tests/kafka-2/application/build.gradle b/dd-smoke-tests/kafka-2/application/build.gradle index 31411ab9e3e..6c0627d7632 100644 --- a/dd-smoke-tests/kafka-2/application/build.gradle +++ b/dd-smoke-tests/kafka-2/application/build.gradle @@ -25,16 +25,6 @@ java { sourceCompatibility = JavaVersion.VERSION_1_8 } -// `iastUtilJar` is wired up by the outer `smokeTestApp { projectJar('iastUtilJar', ...) }` -// block in ../build.gradle: it passes the path of the built `:dd-smoke-tests:iast-util` -// jar into this nested build as a Gradle property. We add it as a flat-file dependency -// because the outer build's projects are not addressable from inside the nested build. -if (hasProperty('iastUtilJar')) { - dependencies { - implementation files(property('iastUtilJar')) - } -} - dependencies { implementation('org.springframework.boot:spring-boot-starter-web') implementation('org.springframework.boot:spring-boot-starter-actuator') diff --git a/dd-smoke-tests/kafka-2/build.gradle b/dd-smoke-tests/kafka-2/build.gradle index 3da5e63bd78..0685f5f3999 100644 --- a/dd-smoke-tests/kafka-2/build.gradle +++ b/dd-smoke-tests/kafka-2/build.gradle @@ -12,7 +12,6 @@ smokeTestApp { artifactPath = 'libs/kafka-2-smoketest.jar' sysProperty = 'datadog.smoketest.springboot.shadowJar.path' } - projectJar('iastUtilJar', project(':dd-smoke-tests:iast-util')) } dependencies { diff --git a/dd-smoke-tests/kafka-2/gradle.lockfile b/dd-smoke-tests/kafka-2/gradle.lockfile index ed7f4754dde..65da39a89f6 100644 --- a/dd-smoke-tests/kafka-2/gradle.lockfile +++ b/dd-smoke-tests/kafka-2/gradle.lockfile @@ -179,4 +179,4 @@ org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.21.4=testCompileClasspath,testRuntimeClasspath org.xerial.snappy:snappy-java:1.1.8.1=testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=annotationProcessor,runtimeClasspath,smokeTestAppExtraJarIastUtilJar,spotbugsPlugins,testAnnotationProcessor,testFixturesAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath +empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor,testFixturesAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/dd-smoke-tests/rum/wildfly-15/build.gradle b/dd-smoke-tests/rum/wildfly-15/build.gradle index 4dd772bd308..d32ce0634c0 100644 --- a/dd-smoke-tests/rum/wildfly-15/build.gradle +++ b/dd-smoke-tests/rum/wildfly-15/build.gradle @@ -56,16 +56,12 @@ dependencies { } def appBuildDir = layout.buildDirectory.dir("rm-ear") -evaluationDependsOn(':dd-trace-api') -def apiJarTask = project(':dd-trace-api').tasks.named('jar') // Run the nested EAR build through the Gradle Tooling API. tasks.register('earBuild', NestedGradleBuild) { applicationDir = layout.projectDirectory.dir("rum-ear") applicationBuildDir = appBuildDir tasksToRun = ['assemble'] - projectJar('apiJar', apiJarTask.flatMap { it.archiveFile }) - dependsOn apiJarTask } tasks.named("compileTestGroovy", GroovyCompile) { diff --git a/dd-smoke-tests/spring-boot-2.7-webflux/application/build.gradle b/dd-smoke-tests/spring-boot-2.7-webflux/application/build.gradle index 58a25bc14e9..1e2f3e955da 100644 --- a/dd-smoke-tests/spring-boot-2.7-webflux/application/build.gradle +++ b/dd-smoke-tests/spring-boot-2.7-webflux/application/build.gradle @@ -26,10 +26,4 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation group: 'com.h2database', name: 'h2', version: '2.1.214' compileOnly group:"com.google.code.findbugs", name:"jsr305", version:"3.0.2" - - if (hasProperty('apiJar')) { - implementation files(property('apiJar')) - } else { - implementation "com.datadoghq:dd-trace-api:0.110.0" - } } diff --git a/dd-smoke-tests/spring-boot-2.7-webflux/build.gradle b/dd-smoke-tests/spring-boot-2.7-webflux/build.gradle index f45d3a0089a..381c9ecd6c7 100644 --- a/dd-smoke-tests/spring-boot-2.7-webflux/build.gradle +++ b/dd-smoke-tests/spring-boot-2.7-webflux/build.gradle @@ -12,7 +12,6 @@ smokeTestApp { artifactPath = 'libs/webflux-2.7-smoketest.jar' sysProperty = 'datadog.smoketest.webflux.uberJar.path' } - projectJar('apiJar', project(':dd-trace-api')) } dependencies { diff --git a/dd-smoke-tests/spring-boot-2.7-webflux/gradle.lockfile b/dd-smoke-tests/spring-boot-2.7-webflux/gradle.lockfile index b779974320e..1ebd715d8d5 100644 --- a/dd-smoke-tests/spring-boot-2.7-webflux/gradle.lockfile +++ b/dd-smoke-tests/spring-boot-2.7-webflux/gradle.lockfile @@ -122,4 +122,4 @@ org.tabletest:tabletest-junit:1.2.2=testCompileClasspath,testRuntimeClasspath org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.21.4=testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=annotationProcessor,runtimeClasspath,smokeTestAppExtraJarApiJar,spotbugsPlugins,testAnnotationProcessor +empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor diff --git a/dd-smoke-tests/spring-boot-3.0-webflux/application/build.gradle b/dd-smoke-tests/spring-boot-3.0-webflux/application/build.gradle index 76dcf9c3da2..810a2688d83 100644 --- a/dd-smoke-tests/spring-boot-3.0-webflux/application/build.gradle +++ b/dd-smoke-tests/spring-boot-3.0-webflux/application/build.gradle @@ -27,10 +27,4 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation group: 'com.h2database', name: 'h2', version: '2.1.214' compileOnly group:"com.google.code.findbugs", name:"jsr305", version:"3.0.2" - - if (hasProperty('apiJar')) { - implementation files(property('apiJar')) - } else { - implementation "com.datadoghq:dd-trace-api:1.2.0" - } } diff --git a/dd-smoke-tests/spring-boot-3.0-webflux/build.gradle b/dd-smoke-tests/spring-boot-3.0-webflux/build.gradle index a6b5fe85c1b..16baa866183 100644 --- a/dd-smoke-tests/spring-boot-3.0-webflux/build.gradle +++ b/dd-smoke-tests/spring-boot-3.0-webflux/build.gradle @@ -16,7 +16,6 @@ smokeTestApp { artifactPath = 'libs/webflux-3.0-smoketest.jar' sysProperty = 'datadog.smoketest.webflux.uberJar.path' } - projectJar('apiJar', project(':dd-trace-api')) } dependencies { diff --git a/dd-smoke-tests/spring-boot-3.0-webflux/gradle.lockfile b/dd-smoke-tests/spring-boot-3.0-webflux/gradle.lockfile index 0a383ac1f2b..ffa7cdbd752 100644 --- a/dd-smoke-tests/spring-boot-3.0-webflux/gradle.lockfile +++ b/dd-smoke-tests/spring-boot-3.0-webflux/gradle.lockfile @@ -122,4 +122,4 @@ org.tabletest:tabletest-junit:1.2.2=testCompileClasspath,testRuntimeClasspath org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.21.4=testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=annotationProcessor,runtimeClasspath,smokeTestAppExtraJarApiJar,spotbugsPlugins,testAnnotationProcessor +empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor diff --git a/dd-smoke-tests/spring-boot-3.0-webmvc/application/build.gradle b/dd-smoke-tests/spring-boot-3.0-webmvc/application/build.gradle index c94214d70ba..487b808088a 100644 --- a/dd-smoke-tests/spring-boot-3.0-webmvc/application/build.gradle +++ b/dd-smoke-tests/spring-boot-3.0-webmvc/application/build.gradle @@ -27,11 +27,4 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation group: 'com.h2database', name: 'h2', version: '2.1.214' compileOnly group:"com.google.code.findbugs", name:"jsr305", version:"3.0.2" - - - if (hasProperty('apiJar')) { - implementation files(property('apiJar')) - } else { - implementation "com.datadoghq:dd-trace-api:1.2.0" - } } diff --git a/dd-smoke-tests/spring-boot-3.0-webmvc/build.gradle b/dd-smoke-tests/spring-boot-3.0-webmvc/build.gradle index ca46c109f87..18bd3001e7c 100644 --- a/dd-smoke-tests/spring-boot-3.0-webmvc/build.gradle +++ b/dd-smoke-tests/spring-boot-3.0-webmvc/build.gradle @@ -16,7 +16,6 @@ smokeTestApp { artifactPath = 'libs/webmvc-3.0-smoketest.jar' sysProperty = 'datadog.smoketest.springboot.uberJar.path' } - projectJar('apiJar', project(':dd-trace-api')) } dependencies { diff --git a/dd-smoke-tests/spring-boot-3.0-webmvc/gradle.lockfile b/dd-smoke-tests/spring-boot-3.0-webmvc/gradle.lockfile index 6069aa936b8..ea9ef3244cb 100644 --- a/dd-smoke-tests/spring-boot-3.0-webmvc/gradle.lockfile +++ b/dd-smoke-tests/spring-boot-3.0-webmvc/gradle.lockfile @@ -122,4 +122,4 @@ org.tabletest:tabletest-junit:1.2.2=testCompileClasspath,testRuntimeClasspath org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.21.4=testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=annotationProcessor,runtimeClasspath,smokeTestAppExtraJarApiJar,spotbugsPlugins,testAnnotationProcessor +empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor diff --git a/dd-smoke-tests/spring-boot-3.3-webmvc/application/build.gradle b/dd-smoke-tests/spring-boot-3.3-webmvc/application/build.gradle index 0ab5e0481a4..57ed9252722 100644 --- a/dd-smoke-tests/spring-boot-3.3-webmvc/application/build.gradle +++ b/dd-smoke-tests/spring-boot-3.3-webmvc/application/build.gradle @@ -28,11 +28,4 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation group: 'com.h2database', name: 'h2', version: '2.1.214' compileOnly group:"com.google.code.findbugs", name:"jsr305", version:"3.0.2" - - - if (hasProperty('apiJar')) { - implementation files(property('apiJar')) - } else { - implementation "com.datadoghq:dd-trace-api:1.2.0" - } } diff --git a/dd-smoke-tests/spring-boot-3.3-webmvc/build.gradle b/dd-smoke-tests/spring-boot-3.3-webmvc/build.gradle index 278a7c6e739..ec7c362c9a1 100644 --- a/dd-smoke-tests/spring-boot-3.3-webmvc/build.gradle +++ b/dd-smoke-tests/spring-boot-3.3-webmvc/build.gradle @@ -16,7 +16,6 @@ smokeTestApp { artifactPath = 'libs/webmvc-3.3-smoketest.jar' sysProperty = 'datadog.smoketest.springboot.uberJar.path' } - projectJar('apiJar', project(':dd-trace-api')) } dependencies { diff --git a/dd-smoke-tests/spring-boot-3.3-webmvc/gradle.lockfile b/dd-smoke-tests/spring-boot-3.3-webmvc/gradle.lockfile index 68ff85edbf7..6d03d465147 100644 --- a/dd-smoke-tests/spring-boot-3.3-webmvc/gradle.lockfile +++ b/dd-smoke-tests/spring-boot-3.3-webmvc/gradle.lockfile @@ -122,4 +122,4 @@ org.tabletest:tabletest-junit:1.2.2=testCompileClasspath,testRuntimeClasspath org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.21.4=testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=annotationProcessor,runtimeClasspath,smokeTestAppExtraJarApiJar,spotbugsPlugins,testAnnotationProcessor +empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor diff --git a/dd-smoke-tests/vertx-3.4/build.gradle b/dd-smoke-tests/vertx-3.4/build.gradle index a2f900c3c61..cb49858b575 100644 --- a/dd-smoke-tests/vertx-3.4/build.gradle +++ b/dd-smoke-tests/vertx-3.4/build.gradle @@ -14,7 +14,6 @@ smokeTestApp { artifactPath = 'libs/vertx-3.4-1.0.0-SNAPSHOT-fat.jar' sysProperty = 'datadog.smoketest.vertx.uberJar.path' } - projectJar('apiJar', project(':dd-trace-api')) } dependencies { diff --git a/dd-smoke-tests/vertx-3.4/gradle.lockfile b/dd-smoke-tests/vertx-3.4/gradle.lockfile index ca94970f6c7..e8a60c366e6 100644 --- a/dd-smoke-tests/vertx-3.4/gradle.lockfile +++ b/dd-smoke-tests/vertx-3.4/gradle.lockfile @@ -127,4 +127,4 @@ org.tabletest:tabletest-junit:1.2.2=testCompileClasspath,testRuntimeClasspath org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.21.4=testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=annotationProcessor,runtimeClasspath,smokeTestAppExtraJarApiJar,spotbugsPlugins,testAnnotationProcessor,testFixturesAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath +empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor,testFixturesAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/dd-smoke-tests/vertx-3.9-resteasy/build.gradle b/dd-smoke-tests/vertx-3.9-resteasy/build.gradle index cec001ad620..bc6b022dd6d 100644 --- a/dd-smoke-tests/vertx-3.9-resteasy/build.gradle +++ b/dd-smoke-tests/vertx-3.9-resteasy/build.gradle @@ -13,7 +13,6 @@ smokeTestApp { artifactPath = 'libs/vertx-3.9-resteasy-1.0.0-SNAPSHOT-fat.jar' sysProperty = 'datadog.smoketest.vertx.uberJar.path' } - projectJar('apiJar', project(':dd-trace-api')) } dependencies { diff --git a/dd-smoke-tests/vertx-3.9-resteasy/gradle.lockfile b/dd-smoke-tests/vertx-3.9-resteasy/gradle.lockfile index fc01499b6f7..df2ed0dc12b 100644 --- a/dd-smoke-tests/vertx-3.9-resteasy/gradle.lockfile +++ b/dd-smoke-tests/vertx-3.9-resteasy/gradle.lockfile @@ -122,4 +122,4 @@ org.tabletest:tabletest-junit:1.2.2=testCompileClasspath,testRuntimeClasspath org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.21.4=testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=annotationProcessor,runtimeClasspath,smokeTestAppExtraJarApiJar,spotbugsPlugins,testAnnotationProcessor +empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor diff --git a/dd-smoke-tests/vertx-3.9/build.gradle b/dd-smoke-tests/vertx-3.9/build.gradle index 1ec45904cea..8d2bf6e471e 100644 --- a/dd-smoke-tests/vertx-3.9/build.gradle +++ b/dd-smoke-tests/vertx-3.9/build.gradle @@ -13,7 +13,6 @@ smokeTestApp { artifactPath = 'libs/vertx-3.9-1.0.0-SNAPSHOT-fat.jar' sysProperty = 'datadog.smoketest.vertx.uberJar.path' } - projectJar('apiJar', project(':dd-trace-api')) } dependencies { diff --git a/dd-smoke-tests/vertx-3.9/gradle.lockfile b/dd-smoke-tests/vertx-3.9/gradle.lockfile index ccf878cc619..37936affd68 100644 --- a/dd-smoke-tests/vertx-3.9/gradle.lockfile +++ b/dd-smoke-tests/vertx-3.9/gradle.lockfile @@ -128,4 +128,4 @@ org.tabletest:tabletest-junit:1.2.2=testCompileClasspath,testRuntimeClasspath org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.21.4=testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=annotationProcessor,runtimeClasspath,smokeTestAppExtraJarApiJar,spotbugsPlugins,testAnnotationProcessor +empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor diff --git a/dd-smoke-tests/vertx-4.2/build.gradle b/dd-smoke-tests/vertx-4.2/build.gradle index b36ab24d335..8879a970a5e 100644 --- a/dd-smoke-tests/vertx-4.2/build.gradle +++ b/dd-smoke-tests/vertx-4.2/build.gradle @@ -13,7 +13,6 @@ smokeTestApp { artifactPath = 'libs/vertx-4.2-1.0.0-SNAPSHOT-fat.jar' sysProperty = 'datadog.smoketest.vertx.uberJar.path' } - projectJar('apiJar', project(':dd-trace-api')) } dependencies { diff --git a/dd-smoke-tests/vertx-4.2/gradle.lockfile b/dd-smoke-tests/vertx-4.2/gradle.lockfile index f7f03c6b64d..b5eff801f62 100644 --- a/dd-smoke-tests/vertx-4.2/gradle.lockfile +++ b/dd-smoke-tests/vertx-4.2/gradle.lockfile @@ -127,4 +127,4 @@ org.tabletest:tabletest-junit:1.2.2=testCompileClasspath,testRuntimeClasspath org.tabletest:tabletest-parser:1.2.1=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.21.4=testCompileClasspath,testRuntimeClasspath org.xmlresolver:xmlresolver:5.3.3=spotbugs -empty=annotationProcessor,runtimeClasspath,smokeTestAppExtraJarApiJar,spotbugsPlugins,testAnnotationProcessor +empty=annotationProcessor,runtimeClasspath,spotbugsPlugins,testAnnotationProcessor diff --git a/dd-smoke-tests/wildfly/build.gradle b/dd-smoke-tests/wildfly/build.gradle index ef5b9c9c317..210e7a10cf1 100644 --- a/dd-smoke-tests/wildfly/build.gradle +++ b/dd-smoke-tests/wildfly/build.gradle @@ -56,16 +56,12 @@ dependencies { } def appBuildDir = layout.buildDirectory.dir("spring-ear") -evaluationDependsOn(':dd-trace-api') -def apiJarTask = project(':dd-trace-api').tasks.named('jar') // Run the nested EAR build through the Gradle Tooling API. tasks.register('earBuild', NestedGradleBuild) { applicationDir = layout.projectDirectory.dir("spring-ear") applicationBuildDir = appBuildDir tasksToRun = ['assemble'] - projectJar('apiJar', apiJarTask.flatMap { it.archiveFile }) - dependsOn apiJarTask } tasks.named("compileTestGroovy", GroovyCompile) { diff --git a/dd-smoke-tests/wildfly/spring-ear/build.gradle b/dd-smoke-tests/wildfly/spring-ear/build.gradle index df6b5a82cb0..e021ec72721 100644 --- a/dd-smoke-tests/wildfly/spring-ear/build.gradle +++ b/dd-smoke-tests/wildfly/spring-ear/build.gradle @@ -25,10 +25,4 @@ java { dependencies { earlib 'org.springframework:spring-webmvc:5.3.0' deploy project(path: ':war', configuration: 'archives') - - if (hasProperty('apiJar')) { - implementation files(property('apiJar')) - } else { - implementation "com.datadoghq:dd-trace-api:1.2.0" - } }