From 1b46292f36d865115bb1a17ea524f10f6ac34689 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Mon, 26 Oct 2026 16:32:43 +0100 Subject: [PATCH] test(spring-boot): Drop Spring Boot 2.4 to 2.6 from the test matrix Spring Boot 2.4 to 2.6 are long past end of life. They were the only reason the Boot 2 suites left GraphQL and Kafka out of their compilation below 2.7, which stands in the way of compiling the suites once and running them on each Boot version's classpath (JAVA-802). The Kafka beans stay in a profile, so only the Kafka tests need a broker. Co-Authored-By: Claude --- .github/workflows/spring-boot-2-matrix.yml | 2 +- sentry-spring-boot/build.gradle.kts | 63 ++++++------------- .../boot/agentfixture/KafkaController.kt | 4 +- .../boot/integrationtest/KafkaController.kt | 3 +- .../integrationtest/KafkaIntegrationTest.kt | 4 +- .../KafkaOtelCoexistenceIntegrationTest.kt | 4 +- .../KafkaController.kt | 4 +- .../KafkaOtelCoexistenceIntegrationTest.kt | 4 +- 8 files changed, 32 insertions(+), 56 deletions(-) diff --git a/.github/workflows/spring-boot-2-matrix.yml b/.github/workflows/spring-boot-2-matrix.yml index edfe9e74fc..3ee4553cf2 100644 --- a/.github/workflows/spring-boot-2-matrix.yml +++ b/.github/workflows/spring-boot-2-matrix.yml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - springboot-version: [ '2.4.13', '2.5.15', '2.6.15', '2.7.0', '2.7.18' ] + springboot-version: [ '2.7.0', '2.7.18' ] name: Spring Boot ${{ matrix.springboot-version }} env: diff --git a/sentry-spring-boot/build.gradle.kts b/sentry-spring-boot/build.gradle.kts index 151d5a829d..3f24e73dc9 100644 --- a/sentry-spring-boot/build.gradle.kts +++ b/sentry-spring-boot/build.gradle.kts @@ -21,9 +21,8 @@ tasks.named("compileKotlin") { // Spring scans the integration test apps' own bytecode with its repackaged ASM at startup, and // the ASM in Spring before 5.3.26 fails on class files as new as the toolchain's: "Unsupported -// class file major version 65". In the Spring Boot 2.x matrix, 2.4.13 (Spring 5.3.13) reads up -// to Java 18 and 2.7.0 (Spring 5.3.20) up to Java 19, so the suites target 17. Remove this once -// the matrix drops 2.4.13 and moves 2.7.0 to 2.7.10 or later. +// class file major version 65". The Spring Boot 2.x matrix's 2.7.0 (Spring 5.3.20) reads up to +// Java 19, so the suites target 17. Remove this once the matrix moves 2.7.0 to 2.7.10 or later. // The suites are Kotlin only. Their Java tasks keep the toolchain's level, because it decides // which Java version their classpaths ask for, and sentry-test-support needs the toolchain's. tasks @@ -137,13 +136,6 @@ tasks.jar { } } -// Spring Boot supports GraphQL only from 2.7, and its Kafka auto-configuration needs 2.7 for the -// spring-kafka version Sentry integrates with. The Spring Boot 2 matrix also covers older versions. -val bootSupportsGraphqlAndKafka = - libs.versions.springboot2.get().split(".").let { (major, minor) -> - major.toInt() > 2 || minor.toInt() >= 7 - } - // The OpenTelemetry agent tests run this app in a child JVM, on its own classpath like a real app // with the agent attached, rather than on the test's classpath. val agentFixture = sourceSets.create("agentFixture") @@ -164,20 +156,18 @@ dependencies { "agentFixtureImplementation"(platform(libs.springboot2.bom)) "agentFixtureImplementation"(projects.sentrySpringBootStarter) "agentFixtureImplementation"(projects.sentryAsyncProfiler) + "agentFixtureImplementation"(projects.sentryGraphql) "agentFixtureImplementation"(projects.sentryJdbc) + "agentFixtureImplementation"(projects.sentryKafka) "agentFixtureImplementation"(projects.sentryLogback) "agentFixtureImplementation"(kotlin(Config.kotlinStdLib)) "agentFixtureImplementation"(libs.otel) + "agentFixtureImplementation"(libs.springboot.starter.graphql) "agentFixtureImplementation"(libs.springboot.starter.jdbc) "agentFixtureImplementation"(libs.springboot.starter.web) "agentFixtureImplementation"(libs.springboot.starter.webflux) + "agentFixtureImplementation"(libs.spring.kafka2) "agentFixtureRuntimeOnly"(libs.hsqldb) - if (bootSupportsGraphqlAndKafka) { - "agentFixtureImplementation"(projects.sentryGraphql) - "agentFixtureImplementation"(projects.sentryKafka) - "agentFixtureImplementation"(libs.springboot.starter.graphql) - "agentFixtureImplementation"(libs.spring.kafka2) - } otelAgentJar(projects.sentryOpentelemetry.sentryOpentelemetryAgent) } @@ -192,7 +182,9 @@ testing { implementation(platform(libs.springboot2.bom)) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryAsyncProfiler) + implementation(projects.sentryGraphql) implementation(projects.sentryJdbc) + implementation(projects.sentryKafka) implementation(projects.sentryLogback) implementation(projects.sentryOkhttp) implementation(projects.sentryTestSupport) @@ -202,18 +194,14 @@ testing { implementation(libs.okhttp) implementation(libs.springboot.starter.aop) implementation(libs.springboot.starter.cache) + implementation(libs.springboot.starter.graphql) implementation(libs.springboot.starter.jdbc) implementation(libs.springboot.starter.test) implementation(libs.springboot.starter.web) implementation(libs.springboot.starter.webflux) + implementation(libs.spring.kafka2) + implementation(libs.spring.kafka2.test) runtimeOnly(libs.hsqldb) - if (bootSupportsGraphqlAndKafka) { - implementation(projects.sentryGraphql) - implementation(projects.sentryKafka) - implementation(libs.springboot.starter.graphql) - implementation(libs.spring.kafka2) - implementation(libs.spring.kafka2.test) - } } } @@ -224,16 +212,14 @@ testing { implementation(platform(libs.springboot2.bom)) implementation(projects.sentrySpringBootStarter) implementation(projects.sentryAsyncProfiler) + implementation(projects.sentryGraphql) implementation(projects.sentryLogback) implementation(projects.sentryTestSupport) implementation(libs.kotlin.test.junit) implementation(libs.google.truth) + implementation(libs.springboot.starter.graphql) implementation(libs.springboot.starter.test) implementation(libs.springboot.starter.webflux) - if (bootSupportsGraphqlAndKafka) { - implementation(projects.sentryGraphql) - implementation(libs.springboot.starter.graphql) - } } } @@ -246,24 +232,22 @@ testing { implementation(projects.sentrySpringBootStarter) implementation(projects.sentryOpentelemetry.sentryOpentelemetryAgentlessSpring) implementation(projects.sentryAsyncProfiler) + implementation(projects.sentryGraphql) implementation(projects.sentryJdbc) + implementation(projects.sentryKafka) implementation(projects.sentryLogback) implementation(projects.sentryTestSupport) implementation(libs.kotlin.test.junit) implementation(libs.google.truth) implementation(libs.springboot.starter.aop) + implementation(libs.springboot.starter.graphql) implementation(libs.springboot.starter.jdbc) implementation(libs.springboot.starter.test) implementation(libs.springboot.starter.web) implementation(libs.springboot.starter.webflux) + implementation(libs.spring.kafka2) + implementation(libs.spring.kafka2.test) runtimeOnly(libs.hsqldb) - if (bootSupportsGraphqlAndKafka) { - implementation(projects.sentryGraphql) - implementation(projects.sentryKafka) - implementation(libs.springboot.starter.graphql) - implementation(libs.spring.kafka2) - implementation(libs.spring.kafka2.test) - } } } @@ -278,9 +262,7 @@ testing { // For TestRestTemplate. Only the app's JVM runs the agent, so it doesn't trace the tests. implementation(libs.springboot.starter.test) implementation(libs.springboot.starter.web) - if (bootSupportsGraphqlAndKafka) { - implementation(libs.spring.kafka2.test) - } + implementation(libs.spring.kafka2.test) } targets.all { testTask.configure { runAgentFixture(autoInit = true) } } } @@ -324,10 +306,5 @@ listOf( "compileIntegrationTestOtelAgentKotlin", ) .forEach { - tasks.named(it) { - compilerOptions.javaParameters = true - if (!bootSupportsGraphqlAndKafka) { - exclude("**/Graphql*", "**/Greeting*", "**/Kafka*") - } - } + tasks.named(it) { compilerOptions.javaParameters = true } } diff --git a/sentry-spring-boot/src/agentFixture/kotlin/io/sentry/spring/boot/agentfixture/KafkaController.kt b/sentry-spring-boot/src/agentFixture/kotlin/io/sentry/spring/boot/agentfixture/KafkaController.kt index 7566632434..28cf59e737 100644 --- a/sentry-spring-boot/src/agentFixture/kotlin/io/sentry/spring/boot/agentfixture/KafkaController.kt +++ b/sentry-spring-boot/src/agentFixture/kotlin/io/sentry/spring/boot/agentfixture/KafkaController.kt @@ -11,8 +11,8 @@ import org.springframework.web.bind.annotation.RestController const val KAFKA_TOPIC = "sentry-topic" -// Kafka only works with Spring Boot 2.7 and later, so its beans belong to a profile rather than to -// the app most tests share. See KafkaOtelCoexistenceIntegrationTest. +// The beans belong to a profile, so only the app KafkaOtelCoexistenceIntegrationTest starts needs a +// broker. @RestController @Profile("kafka") diff --git a/sentry-spring-boot/src/integrationTest/kotlin/io/sentry/spring/boot/integrationtest/KafkaController.kt b/sentry-spring-boot/src/integrationTest/kotlin/io/sentry/spring/boot/integrationtest/KafkaController.kt index 04922bdae0..1613809885 100644 --- a/sentry-spring-boot/src/integrationTest/kotlin/io/sentry/spring/boot/integrationtest/KafkaController.kt +++ b/sentry-spring-boot/src/integrationTest/kotlin/io/sentry/spring/boot/integrationtest/KafkaController.kt @@ -11,8 +11,7 @@ import org.springframework.web.bind.annotation.RestController const val KAFKA_TOPIC = "sentry-topic" -// Kafka only works with Spring Boot 2.7 and later, so its beans and broker belong to a profile -// rather than to every test's context. See KafkaIntegrationTest. +// The beans belong to a profile, so only KafkaIntegrationTest's context needs a broker. @RestController @Profile("kafka") diff --git a/sentry-spring-boot/src/integrationTest/kotlin/io/sentry/spring/boot/integrationtest/KafkaIntegrationTest.kt b/sentry-spring-boot/src/integrationTest/kotlin/io/sentry/spring/boot/integrationtest/KafkaIntegrationTest.kt index 6bd290baf7..e6e8241268 100644 --- a/sentry-spring-boot/src/integrationTest/kotlin/io/sentry/spring/boot/integrationtest/KafkaIntegrationTest.kt +++ b/sentry-spring-boot/src/integrationTest/kotlin/io/sentry/spring/boot/integrationtest/KafkaIntegrationTest.kt @@ -11,8 +11,8 @@ import org.springframework.test.context.TestPropertySource /** * A message sent through Kafka is traced on both sides: where it's published and processed. * - * Unlike the other tests, this one runs its own application context with an in-JVM broker, because - * the shared context has to work on Spring Boot versions without Kafka support. + * Unlike the other tests, this one runs its own application context with an in-JVM broker, so the + * shared context doesn't need one. */ @ActiveProfiles("kafka") @EmbeddedKafka(topics = [KAFKA_TOPIC], bootstrapServersProperty = "spring.kafka.bootstrap-servers") diff --git a/sentry-spring-boot/src/integrationTestOtelAgent/kotlin/io/sentry/spring/boot/otelagentintegrationtest/KafkaOtelCoexistenceIntegrationTest.kt b/sentry-spring-boot/src/integrationTestOtelAgent/kotlin/io/sentry/spring/boot/otelagentintegrationtest/KafkaOtelCoexistenceIntegrationTest.kt index c786274b9e..6913a908fa 100644 --- a/sentry-spring-boot/src/integrationTestOtelAgent/kotlin/io/sentry/spring/boot/otelagentintegrationtest/KafkaOtelCoexistenceIntegrationTest.kt +++ b/sentry-spring-boot/src/integrationTestOtelAgent/kotlin/io/sentry/spring/boot/otelagentintegrationtest/KafkaOtelCoexistenceIntegrationTest.kt @@ -12,8 +12,8 @@ import org.springframework.kafka.test.EmbeddedKafkaBroker * With the agent active, OpenTelemetry traces Kafka instead of Sentry's own Spring Kafka * integration. * - * Unlike the other tests, this one starts an app of its own, with Kafka and an in-JVM broker. The - * shared app leaves them out, because it has to work on Spring Boot versions without Kafka support. + * Unlike the other tests, this one starts an app of its own, with Kafka and an in-JVM broker, so + * the shared app doesn't need a broker. */ class KafkaOtelCoexistenceIntegrationTest : IntegrationTest() { override val app: AgentApp diff --git a/sentry-spring-boot/src/integrationTestOtelNoAgent/kotlin/io/sentry/spring/boot/otelnoagentintegrationtest/KafkaController.kt b/sentry-spring-boot/src/integrationTestOtelNoAgent/kotlin/io/sentry/spring/boot/otelnoagentintegrationtest/KafkaController.kt index e564146043..24f6ed7b6b 100644 --- a/sentry-spring-boot/src/integrationTestOtelNoAgent/kotlin/io/sentry/spring/boot/otelnoagentintegrationtest/KafkaController.kt +++ b/sentry-spring-boot/src/integrationTestOtelNoAgent/kotlin/io/sentry/spring/boot/otelnoagentintegrationtest/KafkaController.kt @@ -11,8 +11,8 @@ import org.springframework.web.bind.annotation.RestController const val KAFKA_TOPIC = "sentry-topic" -// Kafka only works with Spring Boot 2.7 and later, so its beans and broker belong to a profile -// rather than to every test's context. See KafkaOtelCoexistenceIntegrationTest. +// The beans belong to a profile, so only KafkaOtelCoexistenceIntegrationTest's context needs a +// broker. @RestController @Profile("kafka") diff --git a/sentry-spring-boot/src/integrationTestOtelNoAgent/kotlin/io/sentry/spring/boot/otelnoagentintegrationtest/KafkaOtelCoexistenceIntegrationTest.kt b/sentry-spring-boot/src/integrationTestOtelNoAgent/kotlin/io/sentry/spring/boot/otelnoagentintegrationtest/KafkaOtelCoexistenceIntegrationTest.kt index a2a01ce0c4..5efef8875b 100644 --- a/sentry-spring-boot/src/integrationTestOtelNoAgent/kotlin/io/sentry/spring/boot/otelnoagentintegrationtest/KafkaOtelCoexistenceIntegrationTest.kt +++ b/sentry-spring-boot/src/integrationTestOtelNoAgent/kotlin/io/sentry/spring/boot/otelnoagentintegrationtest/KafkaOtelCoexistenceIntegrationTest.kt @@ -11,8 +11,8 @@ import org.springframework.test.context.TestPropertySource /** * With OpenTelemetry active, it traces Kafka instead of Sentry's own Spring Kafka integration. * - * Unlike the other tests, this one adds Kafka and an in-JVM broker to its application context. The - * others leave them out, because they have to work on Spring Boot versions without Kafka support. + * Unlike the other tests, this one adds Kafka and an in-JVM broker to its application context, so + * the others don't need a broker. */ @ActiveProfiles("kafka") @EmbeddedKafka(topics = [KAFKA_TOPIC], bootstrapServersProperty = "spring.kafka.bootstrap-servers")