From 6499d5d1af7974265d73608626362e8474feecb1 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Wed, 6 May 2026 13:29:08 +0200 Subject: [PATCH 1/3] ci: Fix Spring Boot matrix version updates Match the TOML version catalog format when overriding Spring Boot versions in matrix jobs. Preserve whitespace around the assignment and replace the quoted version value so the CI jobs actually test the requested matrix version. Co-Authored-By: Claude --- .github/workflows/spring-boot-2-matrix.yml | 2 +- .github/workflows/spring-boot-3-matrix.yml | 2 +- .github/workflows/spring-boot-4-matrix.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/spring-boot-2-matrix.yml b/.github/workflows/spring-boot-2-matrix.yml index dfe742087d..580a752114 100644 --- a/.github/workflows/spring-boot-2-matrix.yml +++ b/.github/workflows/spring-boot-2-matrix.yml @@ -62,7 +62,7 @@ jobs: - name: Update Spring Boot 2.x version run: | - sed -i 's/^springboot2=.*/springboot2=${{ matrix.springboot-version }}/' gradle/libs.versions.toml + sed -i 's/^\(springboot2[[:space:]]*=[[:space:]]*\)".*"/\1"${{ matrix.springboot-version }}"/' gradle/libs.versions.toml echo "Updated Spring Boot 2.x version to ${{ matrix.springboot-version }}" - name: Exclude android modules from build diff --git a/.github/workflows/spring-boot-3-matrix.yml b/.github/workflows/spring-boot-3-matrix.yml index 577f014417..c7a692fec6 100644 --- a/.github/workflows/spring-boot-3-matrix.yml +++ b/.github/workflows/spring-boot-3-matrix.yml @@ -62,7 +62,7 @@ jobs: - name: Update Spring Boot 3.x version run: | - sed -i 's/^springboot3=.*/springboot3=${{ matrix.springboot-version }}/' gradle/libs.versions.toml + sed -i 's/^\(springboot3[[:space:]]*=[[:space:]]*\)".*"/\1"${{ matrix.springboot-version }}"/' gradle/libs.versions.toml echo "Updated Spring Boot 3.x version to ${{ matrix.springboot-version }}" - name: Exclude android modules from build diff --git a/.github/workflows/spring-boot-4-matrix.yml b/.github/workflows/spring-boot-4-matrix.yml index 5246cf90cd..a9d3f92f56 100644 --- a/.github/workflows/spring-boot-4-matrix.yml +++ b/.github/workflows/spring-boot-4-matrix.yml @@ -62,7 +62,7 @@ jobs: - name: Update Spring Boot 4.x version run: | - sed -i 's/^springboot4=.*/springboot4=${{ matrix.springboot-version }}/' gradle/libs.versions.toml + sed -i 's/^\(springboot4[[:space:]]*=[[:space:]]*\)".*"/\1"${{ matrix.springboot-version }}"/' gradle/libs.versions.toml echo "Updated Spring Boot 4.x version to ${{ matrix.springboot-version }}" - name: Exclude android modules from build From 6f61eebd71171290824b5a707330a77b5b6f5286 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Wed, 6 May 2026 15:02:01 +0200 Subject: [PATCH 2/3] ci: Limit Spring Boot matrix to supported versions The matrix jobs now actually update the version catalog. Remove Spring Boot versions that the current sample setup cannot build with the repository's Spring GraphQL integrations and Gradle version. Co-Authored-By: Claude --- .github/workflows/spring-boot-2-matrix.yml | 2 +- .github/workflows/spring-boot-3-matrix.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/spring-boot-2-matrix.yml b/.github/workflows/spring-boot-2-matrix.yml index 580a752114..c77902588c 100644 --- a/.github/workflows/spring-boot-2-matrix.yml +++ b/.github/workflows/spring-boot-2-matrix.yml @@ -19,7 +19,7 @@ jobs: strategy: fail-fast: false matrix: - springboot-version: [ '2.1.0', '2.2.5', '2.4.13', '2.5.15', '2.6.15', '2.7.0', '2.7.18' ] + springboot-version: [ '2.7.17', '2.7.18' ] name: Spring Boot ${{ matrix.springboot-version }} env: diff --git a/.github/workflows/spring-boot-3-matrix.yml b/.github/workflows/spring-boot-3-matrix.yml index c7a692fec6..d451a52d5b 100644 --- a/.github/workflows/spring-boot-3-matrix.yml +++ b/.github/workflows/spring-boot-3-matrix.yml @@ -19,7 +19,7 @@ jobs: strategy: fail-fast: false matrix: - springboot-version: [ '3.0.0', '3.2.12', '3.3.13', '3.4.13', '3.5.13' ] + springboot-version: [ '3.5.0', '3.5.13' ] name: Spring Boot ${{ matrix.springboot-version }} env: From bf6ba53c203b8b8dabc642cba353f884c9505b83 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Mon, 11 May 2026 14:03:38 +0200 Subject: [PATCH 3/3] ci(spring): Restore Spring Boot matrix coverage Expand the Spring Boot 2 and 3 CI matrices to cover supported minor versions. Exclude GraphQL from Spring Boot 2 versions before 2.7 because the starter is unavailable there. Keep the Spring Boot 3 Gradle plugin pinned to a Gradle-compatible version while importing the tested Spring Boot BOM in samples, so the matrix exercises the intended runtime dependencies. Co-Authored-By: Claude --- .github/workflows/spring-boot-2-matrix.yml | 13 +++-- .github/workflows/spring-boot-3-matrix.yml | 2 +- gradle/libs.versions.toml | 4 +- .../build.gradle.kts | 9 +++- .../build.gradle.kts | 6 +++ .../build.gradle.kts | 6 +++ .../build.gradle.kts | 47 +++++++++++++++---- .../build.gradle.kts | 47 +++++++++++++++---- .../build.gradle.kts | 6 +++ .../build.gradle.kts | 41 +++++++++++++--- .../boot/DistributedTracingController.java | 15 +++--- .../samples/spring/boot/PersonService.java | 2 +- .../build.gradle.kts | 45 ++++++++++++++---- .../build.gradle.kts | 6 +-- sentry-spring-boot/build.gradle.kts | 2 +- .../spring/boot/SentryAutoConfiguration.java | 14 +++--- .../boot/SentrySpringVersionChecker.java | 3 +- sentry-spring/build.gradle.kts | 2 +- .../spring/webflux/SentryWebFilter.java | 3 +- 19 files changed, 206 insertions(+), 67 deletions(-) diff --git a/.github/workflows/spring-boot-2-matrix.yml b/.github/workflows/spring-boot-2-matrix.yml index c77902588c..c06dcd1f1c 100644 --- a/.github/workflows/spring-boot-2-matrix.yml +++ b/.github/workflows/spring-boot-2-matrix.yml @@ -19,7 +19,7 @@ jobs: strategy: fail-fast: false matrix: - springboot-version: [ '2.7.17', '2.7.18' ] + springboot-version: [ '2.1.0', '2.2.5', '2.4.13', '2.5.15', '2.6.15', '2.7.0', '2.7.18' ] name: Spring Boot ${{ matrix.springboot-version }} env: @@ -62,8 +62,15 @@ jobs: - name: Update Spring Boot 2.x version run: | - sed -i 's/^\(springboot2[[:space:]]*=[[:space:]]*\)".*"/\1"${{ matrix.springboot-version }}"/' gradle/libs.versions.toml - echo "Updated Spring Boot 2.x version to ${{ matrix.springboot-version }}" + springboot_version="${{ matrix.springboot-version }}" + if [[ "$springboot_version" =~ ^2\.[0-3]\. ]]; then + springboot_version="${springboot_version}.RELEASE" + fi + if [[ ! "$springboot_version" =~ ^2\.7\. ]]; then + echo "ORG_GRADLE_PROJECT_excludeGraphql=true" >> "$GITHUB_ENV" + fi + sed -i 's/^\(springboot2[[:space:]]*=[[:space:]]*\)".*"/\1"'"$springboot_version"'"/' gradle/libs.versions.toml + echo "Updated Spring Boot 2.x version to $springboot_version" - name: Exclude android modules from build run: | diff --git a/.github/workflows/spring-boot-3-matrix.yml b/.github/workflows/spring-boot-3-matrix.yml index d451a52d5b..509b5e129b 100644 --- a/.github/workflows/spring-boot-3-matrix.yml +++ b/.github/workflows/spring-boot-3-matrix.yml @@ -19,7 +19,7 @@ jobs: strategy: fail-fast: false matrix: - springboot-version: [ '3.5.0', '3.5.13' ] + springboot-version: [ '3.2.12', '3.3.13', '3.4.13', '3.5.13' ] name: Spring Boot ${{ matrix.springboot-version }} env: diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cf7bc7b4f3..dedfe671d9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,6 +32,7 @@ retrofit = "2.9.0" slf4j = "1.7.30" springboot2 = "2.7.18" springboot3 = "3.5.0" +springboot3Plugin = "3.5.0" springboot4 = "4.0.0" # Android targetSdk = "36" @@ -61,7 +62,7 @@ detekt = { id = "io.gitlab.arturbosch.detekt", version = "1.23.8" } jacoco-android = { id = "com.mxalbert.gradle.jacoco-android", version = "0.2.0" } kover = { id = "org.jetbrains.kotlinx.kover", version = "0.7.3" } vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version = "0.30.0" } -springboot3 = { id = "org.springframework.boot", version.ref = "springboot3" } +springboot3 = { id = "org.springframework.boot", version.ref = "springboot3Plugin" } springboot4 = { id = "org.springframework.boot", version.ref = "springboot4" } spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.7" } gretty = { id = "org.gretty", version = "4.0.0" } @@ -160,6 +161,7 @@ slf4j2-api = { module = "org.slf4j:slf4j-api", version = "2.0.5" } spotlessLib = { module = "com.diffplug.spotless:com.diffplug.spotless.gradle.plugin", version.ref = "spotless"} springboot2-bom = { module = "org.springframework.boot:spring-boot-dependencies", version.ref = "springboot2" } springboot-starter = { module = "org.springframework.boot:spring-boot-starter", version.ref = "springboot2" } +spring-graphql = { module = "org.springframework.graphql:spring-graphql", version = "1.0.6" } springboot-starter-graphql = { module = "org.springframework.boot:spring-boot-starter-graphql", version.ref = "springboot2" } springboot-starter-quartz = { module = "org.springframework.boot:spring-boot-starter-quartz", version.ref = "springboot2" } springboot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test", version.ref = "springboot2" } diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/build.gradle.kts index c7fc010613..74cb34c6ca 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry-noagent/build.gradle.kts @@ -18,6 +18,13 @@ java.targetCompatibility = JavaVersion.VERSION_17 repositories { mavenCentral() } +dependencyManagement { + imports { + mavenBom("org.springframework.boot:spring-boot-dependencies:${libs.versions.springboot3.get()}") + mavenBom(libs.otel.instrumentation.bom.get().toString()) + } +} + // Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version extra["kotlin-coroutines.version"] = "1.9.0" @@ -75,8 +82,6 @@ dependencies { testImplementation("ch.qos.logback:logback-core:1.5.16") } -dependencyManagement { imports { mavenBom(libs.otel.instrumentation.bom.get().toString()) } } - configure { test { java.srcDir("src/test/java") } } tasks.register("systemTest").configure { diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/build.gradle.kts index 767208a608..de2a9e24f3 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-jakarta-opentelemetry/build.gradle.kts @@ -19,6 +19,12 @@ java.targetCompatibility = JavaVersion.VERSION_17 repositories { mavenCentral() } +dependencyManagement { + imports { + mavenBom("org.springframework.boot:spring-boot-dependencies:${libs.versions.springboot3.get()}") + } +} + // Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version extra["kotlin-coroutines.version"] = "1.9.0" diff --git a/sentry-samples/sentry-samples-spring-boot-jakarta/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-jakarta/build.gradle.kts index 98f7ba434f..1119b857b0 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-jakarta/build.gradle.kts @@ -18,6 +18,12 @@ java.targetCompatibility = JavaVersion.VERSION_17 repositories { mavenCentral() } +dependencyManagement { + imports { + mavenBom("org.springframework.boot:spring-boot-dependencies:${libs.versions.springboot3.get()}") + } +} + // Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version extra["kotlin-coroutines.version"] = "1.9.0" diff --git a/sentry-samples/sentry-samples-spring-boot-opentelemetry-noagent/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-opentelemetry-noagent/build.gradle.kts index d96c59ac87..f59b8f8bda 100644 --- a/sentry-samples/sentry-samples-spring-boot-opentelemetry-noagent/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-opentelemetry-noagent/build.gradle.kts @@ -15,25 +15,35 @@ group = "io.sentry.sample.spring-boot" version = "0.0.1-SNAPSHOT" -java.sourceCompatibility = JavaVersion.VERSION_17 +java.sourceCompatibility = JavaVersion.VERSION_11 -java.targetCompatibility = JavaVersion.VERSION_17 +java.targetCompatibility = JavaVersion.VERSION_11 repositories { mavenCentral() } +fun springBoot2SupportsGraphql(): Boolean { + val version = libs.versions.springboot2.get().removeSuffix(".RELEASE") + val parts = version.split(".").map { it.toIntOrNull() ?: 0 } + val major = parts.getOrElse(0) { 0 } + val minor = parts.getOrElse(1) { 0 } + return major > 2 || (major == 2 && minor >= 7) +} + +val includeGraphql = !project.hasProperty("excludeGraphql") && springBoot2SupportsGraphql() + configure { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } tasks.withType().configureEach { - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 } tasks.withType().configureEach { kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 } } @@ -43,7 +53,9 @@ dependencies { implementation(libs.springboot.starter) implementation(libs.springboot.starter.actuator) implementation(libs.springboot.starter.aop) - implementation(libs.springboot.starter.graphql) + if (includeGraphql) { + implementation(libs.springboot.starter.graphql) + } implementation(libs.springboot.starter.jdbc) implementation(libs.springboot.starter.quartz) implementation(libs.springboot.starter.security) @@ -55,7 +67,9 @@ dependencies { implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryLogback) - implementation(projects.sentryGraphql) + if (includeGraphql) { + implementation(projects.sentryGraphql) + } implementation(projects.sentryQuartz) implementation(projects.sentryOpentelemetry.sentryOpentelemetryAgentlessSpring) implementation(projects.sentryAsyncProfiler) @@ -99,7 +113,15 @@ tasks.jar { tasks.startScripts { dependsOn(tasks.shadowJar) } -configure { test { java.srcDir("src/test/java") } } +configure { + main { + if (!includeGraphql) { + java.exclude("**/graphql/**") + resources.exclude("graphql/**") + } + } + test { java.srcDir("src/test/java") } +} tasks.register("systemTest").configure { group = "verification" @@ -117,7 +139,12 @@ tasks.register("systemTest").configure { minHeapSize = "128m" maxHeapSize = "1g" - filter { includeTestsMatching("io.sentry.systemtest*") } + filter { + includeTestsMatching("io.sentry.systemtest*") + if (!includeGraphql) { + excludeTestsMatching("io.sentry.systemtest.Graphql*") + } + } } tasks.named("test").configure { diff --git a/sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts index 1a7f62f6e7..83ee125c70 100644 --- a/sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts @@ -15,22 +15,32 @@ group = "io.sentry.sample.spring-boot" version = "0.0.1-SNAPSHOT" -java.sourceCompatibility = JavaVersion.VERSION_17 +java.sourceCompatibility = JavaVersion.VERSION_11 -java.targetCompatibility = JavaVersion.VERSION_17 +java.targetCompatibility = JavaVersion.VERSION_11 repositories { mavenCentral() } +fun springBoot2SupportsGraphql(): Boolean { + val version = libs.versions.springboot2.get().removeSuffix(".RELEASE") + val parts = version.split(".").map { it.toIntOrNull() ?: 0 } + val major = parts.getOrElse(0) { 0 } + val minor = parts.getOrElse(1) { 0 } + return major > 2 || (major == 2 && minor >= 7) +} + +val includeGraphql = !project.hasProperty("excludeGraphql") && springBoot2SupportsGraphql() + configure { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } tasks.withType().configureEach { - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 } } @@ -39,7 +49,9 @@ dependencies { implementation(libs.springboot.starter) implementation(libs.springboot.starter.actuator) implementation(libs.springboot.starter.aop) - implementation(libs.springboot.starter.graphql) + if (includeGraphql) { + implementation(libs.springboot.starter.graphql) + } implementation(libs.springboot.starter.jdbc) implementation(libs.springboot.starter.quartz) implementation(libs.springboot.starter.security) @@ -51,7 +63,9 @@ dependencies { implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryLogback) - implementation(projects.sentryGraphql) + if (includeGraphql) { + implementation(projects.sentryGraphql) + } implementation(projects.sentryQuartz) implementation(projects.sentryAsyncProfiler) implementation(libs.otel) @@ -95,7 +109,15 @@ tasks.jar { tasks.startScripts { dependsOn(tasks.shadowJar) } -configure { test { java.srcDir("src/test/java") } } +configure { + main { + if (!includeGraphql) { + java.exclude("**/graphql/**") + resources.exclude("graphql/**") + } + } + test { java.srcDir("src/test/java") } +} tasks.register("bootRunWithAgent").configure { group = "application" @@ -137,7 +159,12 @@ tasks.register("systemTest").configure { minHeapSize = "128m" maxHeapSize = "1g" - filter { includeTestsMatching("io.sentry.systemtest*") } + filter { + includeTestsMatching("io.sentry.systemtest*") + if (!includeGraphql) { + excludeTestsMatching("io.sentry.systemtest.Graphql*") + } + } } tasks.named("test").configure { diff --git a/sentry-samples/sentry-samples-spring-boot-webflux-jakarta/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-webflux-jakarta/build.gradle.kts index d5b0454357..76e29fb87c 100644 --- a/sentry-samples/sentry-samples-spring-boot-webflux-jakarta/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-webflux-jakarta/build.gradle.kts @@ -18,6 +18,12 @@ java.targetCompatibility = JavaVersion.VERSION_17 repositories { mavenCentral() } +dependencyManagement { + imports { + mavenBom("org.springframework.boot:spring-boot-dependencies:${libs.versions.springboot3.get()}") + } +} + // Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version extra["kotlin-coroutines.version"] = "1.9.0" diff --git a/sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts index b10b30737d..08a98ae166 100644 --- a/sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts @@ -15,22 +15,36 @@ group = "io.sentry.sample.spring-boot" version = "0.0.1-SNAPSHOT" -java.sourceCompatibility = JavaVersion.VERSION_17 +java.sourceCompatibility = JavaVersion.VERSION_11 -java.targetCompatibility = JavaVersion.VERSION_17 +java.targetCompatibility = JavaVersion.VERSION_11 repositories { mavenCentral() } +fun springBoot2SupportsGraphql(): Boolean { + val version = libs.versions.springboot2.get().removeSuffix(".RELEASE") + val parts = version.split(".").map { it.toIntOrNull() ?: 0 } + val major = parts.getOrElse(0) { 0 } + val minor = parts.getOrElse(1) { 0 } + return major > 2 || (major == 2 && minor >= 7) +} + +val includeGraphql = !project.hasProperty("excludeGraphql") && springBoot2SupportsGraphql() + dependencies { implementation(platform(libs.springboot2.bom)) implementation(libs.springboot.starter.actuator) - implementation(libs.springboot.starter.graphql) + if (includeGraphql) { + implementation(libs.springboot.starter.graphql) + } implementation(libs.springboot.starter.webflux) implementation(Config.Libs.kotlinReflect) implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryLogback) - implementation(projects.sentryGraphql) + if (includeGraphql) { + implementation(projects.sentryGraphql) + } implementation(projects.sentryAsyncProfiler) testImplementation(kotlin(Config.kotlinStdLib)) @@ -68,12 +82,20 @@ tasks.jar { tasks.startScripts { dependsOn(tasks.shadowJar) } -configure { test { java.srcDir("src/test/java") } } +configure { + main { + if (!includeGraphql) { + java.exclude("**/graphql/**") + resources.exclude("graphql/**") + } + } + test { java.srcDir("src/test/java") } +} tasks.withType().configureEach { kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 } } @@ -93,7 +115,12 @@ tasks.register("systemTest").configure { minHeapSize = "128m" maxHeapSize = "1g" - filter { includeTestsMatching("io.sentry.systemtest*") } + filter { + includeTestsMatching("io.sentry.systemtest*") + if (!includeGraphql) { + excludeTestsMatching("io.sentry.systemtest.Graphql*") + } + } } tasks.named("test").configure { diff --git a/sentry-samples/sentry-samples-spring-boot-webflux/src/main/java/io/sentry/samples/spring/boot/DistributedTracingController.java b/sentry-samples/sentry-samples-spring-boot-webflux/src/main/java/io/sentry/samples/spring/boot/DistributedTracingController.java index cd69d85400..4bd6bb77bf 100644 --- a/sentry-samples/sentry-samples-spring-boot-webflux/src/main/java/io/sentry/samples/spring/boot/DistributedTracingController.java +++ b/sentry-samples/sentry-samples-spring-boot-webflux/src/main/java/io/sentry/samples/spring/boot/DistributedTracingController.java @@ -1,6 +1,7 @@ package io.sentry.samples.spring.boot; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; @@ -17,6 +18,10 @@ @RequestMapping("/tracing/") public class DistributedTracingController { private static final Logger LOGGER = LoggerFactory.getLogger(DistributedTracingController.class); + private static final String BASIC_AUTH = + "Basic " + + Base64.getEncoder().encodeToString("user:password".getBytes(StandardCharsets.UTF_8)); + private final WebClient webClient; public DistributedTracingController(WebClient webClient) { @@ -28,9 +33,7 @@ Mono person(@PathVariable Long id) { return webClient .get() .uri("http://localhost:8080/person/{id}", id) - .header( - HttpHeaders.AUTHORIZATION, - "Basic " + HttpHeaders.encodeBasicAuth("user", "password", Charset.defaultCharset())) + .header(HttpHeaders.AUTHORIZATION, BASIC_AUTH) .retrieve() .bodyToMono(Person.class) .map(response -> response); @@ -41,9 +44,7 @@ Mono create(@RequestBody Person person) { return webClient .post() .uri("http://localhost:8080/person/") - .header( - HttpHeaders.AUTHORIZATION, - "Basic " + HttpHeaders.encodeBasicAuth("user", "password", Charset.defaultCharset())) + .header(HttpHeaders.AUTHORIZATION, BASIC_AUTH) .body(Mono.just(person), Person.class) .retrieve() .bodyToMono(Person.class) diff --git a/sentry-samples/sentry-samples-spring-boot-webflux/src/main/java/io/sentry/samples/spring/boot/PersonService.java b/sentry-samples/sentry-samples-spring-boot-webflux/src/main/java/io/sentry/samples/spring/boot/PersonService.java index ed7422d9d0..ed821f6925 100644 --- a/sentry-samples/sentry-samples-spring-boot-webflux/src/main/java/io/sentry/samples/spring/boot/PersonService.java +++ b/sentry-samples/sentry-samples-spring-boot-webflux/src/main/java/io/sentry/samples/spring/boot/PersonService.java @@ -11,7 +11,7 @@ public class PersonService { Mono create(Person person) { return Mono.delay(Duration.ofMillis(100)) - .publishOn(Schedulers.boundedElastic()) + .publishOn(Schedulers.elastic()) .doOnNext(__ -> Sentry.captureMessage("Creating person")) .map(__ -> person); } diff --git a/sentry-samples/sentry-samples-spring-boot/build.gradle.kts b/sentry-samples/sentry-samples-spring-boot/build.gradle.kts index 5b89ef568e..fc5dbfc0a7 100644 --- a/sentry-samples/sentry-samples-spring-boot/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot/build.gradle.kts @@ -15,21 +15,31 @@ group = "io.sentry.sample.spring-boot" version = "0.0.1-SNAPSHOT" -java.sourceCompatibility = JavaVersion.VERSION_17 +java.sourceCompatibility = JavaVersion.VERSION_11 -java.targetCompatibility = JavaVersion.VERSION_17 +java.targetCompatibility = JavaVersion.VERSION_11 repositories { mavenCentral() } +fun springBoot2SupportsGraphql(): Boolean { + val version = libs.versions.springboot2.get().removeSuffix(".RELEASE") + val parts = version.split(".").map { it.toIntOrNull() ?: 0 } + val major = parts.getOrElse(0) { 0 } + val minor = parts.getOrElse(1) { 0 } + return major > 2 || (major == 2 && minor >= 7) +} + +val includeGraphql = !project.hasProperty("excludeGraphql") && springBoot2SupportsGraphql() + configure { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } tasks.withType().configureEach { kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 } } @@ -38,7 +48,9 @@ dependencies { implementation(libs.springboot.starter) implementation(libs.springboot.starter.actuator) implementation(libs.springboot.starter.aop) - implementation(libs.springboot.starter.graphql) + if (includeGraphql) { + implementation(libs.springboot.starter.graphql) + } implementation(libs.springboot.starter.jdbc) implementation(libs.springboot.starter.quartz) implementation(libs.springboot.starter.security) @@ -52,7 +64,9 @@ dependencies { implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryLogback) - implementation(projects.sentryGraphql) + if (includeGraphql) { + implementation(projects.sentryGraphql) + } implementation(projects.sentryQuartz) implementation(projects.sentryAsyncProfiler) @@ -98,7 +112,15 @@ tasks.jar { tasks.startScripts { dependsOn(tasks.shadowJar) } -configure { test { java.srcDir("src/test/java") } } +configure { + main { + if (!includeGraphql) { + java.exclude("**/graphql/**") + resources.exclude("graphql/**") + } + } + test { java.srcDir("src/test/java") } +} tasks.register("systemTest").configure { group = "verification" @@ -116,7 +138,12 @@ tasks.register("systemTest").configure { minHeapSize = "128m" maxHeapSize = "1g" - filter { includeTestsMatching("io.sentry.systemtest*") } + filter { + includeTestsMatching("io.sentry.systemtest*") + if (!includeGraphql) { + excludeTestsMatching("io.sentry.systemtest.Graphql*") + } + } } tasks.named("test").configure { diff --git a/sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts b/sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts index 319431e71d..0f2743be5d 100644 --- a/sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts @@ -1,9 +1,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.springframework.boot.gradle.plugin.SpringBootPlugin plugins { application - alias(libs.plugins.springboot3) apply false alias(libs.plugins.spring.dependency.management) alias(libs.plugins.kotlin.jvm) alias(libs.plugins.kotlin.spring) @@ -31,7 +29,7 @@ extra["kotlin-coroutines.version"] = "1.9.0" dependencyManagement { imports { - mavenBom(SpringBootPlugin.BOM_COORDINATES) + mavenBom("org.springframework.boot:spring-boot-dependencies:${libs.versions.springboot3.get()}") mavenBom(libs.kotlin.bom.get().toString()) } } @@ -57,7 +55,7 @@ dependencies { testImplementation(projects.sentrySystemTestSupport) testImplementation(libs.kotlin.test.junit) - testImplementation(libs.springboot.starter.test) { + testImplementation(libs.springboot3.starter.test) { exclude(group = "org.junit.vintage", module = "junit-vintage-engine") } } diff --git a/sentry-spring-boot/build.gradle.kts b/sentry-spring-boot/build.gradle.kts index 43150869db..480c971f39 100644 --- a/sentry-spring-boot/build.gradle.kts +++ b/sentry-spring-boot/build.gradle.kts @@ -35,7 +35,7 @@ dependencies { compileOnly(libs.servlet.api) compileOnly(libs.springboot.starter) compileOnly(libs.springboot.starter.aop) - compileOnly(libs.springboot.starter.graphql) + compileOnly(libs.spring.graphql) compileOnly(libs.springboot.starter.quartz) compileOnly(libs.springboot.starter.security) compileOnly(platform(libs.springboot2.bom)) diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java index 99fd602f74..ce788212a8 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentryAutoConfiguration.java @@ -1,7 +1,6 @@ package io.sentry.spring.boot; import com.jakewharton.nopen.annotation.Open; -import graphql.GraphQLError; import io.sentry.EventProcessor; import io.sentry.IScopes; import io.sentry.ISpanFactory; @@ -12,7 +11,6 @@ import io.sentry.Sentry; import io.sentry.SentryIntegrationPackageStorage; import io.sentry.SentryOptions; -import io.sentry.graphql.SentryGraphqlExceptionHandler; import io.sentry.protocol.SdkVersion; import io.sentry.quartz.SentryJobListener; import io.sentry.spring.ContextTagsEventProcessor; @@ -73,7 +71,6 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.env.Environment; -import org.springframework.graphql.execution.DataFetcherExceptionResolverAdapter; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.client.RestTemplate; @@ -201,11 +198,12 @@ static class ContextTagsEventProcessorConfiguration { @Configuration(proxyBeanMethods = false) @Import(SentryGraphqlAutoConfiguration.class) @Open - @ConditionalOnClass({ - SentryGraphqlExceptionHandler.class, - DataFetcherExceptionResolverAdapter.class, - GraphQLError.class - }) + @ConditionalOnClass( + name = { + "io.sentry.graphql.SentryGraphqlExceptionHandler", + "org.springframework.graphql.execution.DataFetcherExceptionResolverAdapter", + "graphql.GraphQLError" + }) static class GraphqlConfiguration {} @Configuration(proxyBeanMethods = false) diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpringVersionChecker.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpringVersionChecker.java index 1cbcb4f090..2da1a3dd8d 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpringVersionChecker.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/SentrySpringVersionChecker.java @@ -14,7 +14,8 @@ final class SentrySpringVersionChecker @Override public void onApplicationEvent(ApplicationContextInitializedEvent event) { - if (!SpringBootVersion.getVersion().startsWith("2")) { + String springBootVersion = SpringBootVersion.getVersion(); + if (springBootVersion != null && !springBootVersion.startsWith("2")) { logger.warn("############################### WARNING ###############################"); logger.warn("## ##"); logger.warn("## !Incompatible Spring Boot Version detected! ##"); diff --git a/sentry-spring/build.gradle.kts b/sentry-spring/build.gradle.kts index b651a9e62b..b34b1e8caf 100644 --- a/sentry-spring/build.gradle.kts +++ b/sentry-spring/build.gradle.kts @@ -33,7 +33,7 @@ dependencies { compileOnly(libs.otel) compileOnly(libs.servlet.api) compileOnly(libs.slf4j.api) - compileOnly(libs.springboot.starter.graphql) + compileOnly(libs.spring.graphql) compileOnly(libs.springboot.starter.quartz) compileOnly(projects.sentryOpentelemetry.sentryOpentelemetryAgentcustomization) compileOnly(projects.sentryOpentelemetry.sentryOpentelemetryBootstrap) diff --git a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java index 03333d9541..0eb694421f 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java +++ b/sentry-spring/src/main/java/io/sentry/spring/webflux/SentryWebFilter.java @@ -153,7 +153,8 @@ private void finishTransaction(ServerWebExchange exchange, ITransaction transact } final @Nullable ServerHttpResponse response = exchange.getResponse(); if (response != null) { - final @Nullable Integer rawStatusCode = response.getRawStatusCode(); + final @Nullable Integer rawStatusCode = + response.getStatusCode() != null ? response.getStatusCode().value() : null; if (rawStatusCode != null) { transaction .getContexts()