diff --git a/.github/workflows/spring-boot-2-matrix.yml b/.github/workflows/spring-boot-2-matrix.yml index 38aaacec27a..be0fcd7ec9c 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.4.13', '2.5.15', '2.6.15', '2.7.0', '2.7.18' ] name: Spring Boot ${{ matrix.springboot-version }} env: @@ -62,8 +62,13 @@ jobs: - name: Update Spring Boot 2.x version run: | - sed -i 's/^springboot2=.*/springboot2=${{ 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\.7\. ]]; then + echo "ORG_GRADLE_PROJECT_excludeGraphql=true" >> "$GITHUB_ENV" + echo "ORG_GRADLE_PROJECT_excludeKafka=true" >> "$GITHUB_ENV" + fi + perl -0pi -e 'BEGIN { $v = shift } s/^springboot2[[:space:]]*=[[:space:]]*"\K[^"]*/$v/m or die "::error::springboot2 version entry not found in gradle/libs.versions.toml\n"' "$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 629535e282d..5b7399df5c6 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.2.12', '3.3.13', '3.4.13', '3.5.13' ] name: Spring Boot ${{ matrix.springboot-version }} env: @@ -62,8 +62,9 @@ jobs: - name: Update Spring Boot 3.x version run: | - sed -i 's/^springboot3=.*/springboot3=${{ matrix.springboot-version }}/' gradle/libs.versions.toml - echo "Updated Spring Boot 3.x version to ${{ matrix.springboot-version }}" + springboot_version="${{ matrix.springboot-version }}" + perl -0pi -e 'BEGIN { $v = shift } s/^springboot3[[:space:]]*=[[:space:]]*"\K[^"]*/$v/m or die "::error::springboot3 version entry not found in gradle/libs.versions.toml\n"' "$springboot_version" gradle/libs.versions.toml + echo "Updated Spring Boot 3.x version to $springboot_version" - name: Exclude android modules from build run: | diff --git a/.github/workflows/spring-boot-4-matrix.yml b/.github/workflows/spring-boot-4-matrix.yml index bbd4f986d96..9336f913b0f 100644 --- a/.github/workflows/spring-boot-4-matrix.yml +++ b/.github/workflows/spring-boot-4-matrix.yml @@ -62,8 +62,9 @@ jobs: - name: Update Spring Boot 4.x version run: | - sed -i 's/^springboot4=.*/springboot4=${{ matrix.springboot-version }}/' gradle/libs.versions.toml - echo "Updated Spring Boot 4.x version to ${{ matrix.springboot-version }}" + springboot_version="${{ matrix.springboot-version }}" + perl -0pi -e 'BEGIN { $v = shift } s/^springboot4[[:space:]]*=[[:space:]]*"\K[^"]*/$v/m or die "::error::springboot4 version entry not found in gradle/libs.versions.toml\n"' "$springboot_version" gradle/libs.versions.toml + echo "Updated Spring Boot 4.x version to $springboot_version" - name: Exclude android modules from build run: | diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ab39c981b44..6012ad6153f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -160,6 +160,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 ed0af32b031..7966e621ebd 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 @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -18,6 +19,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" @@ -27,10 +35,10 @@ configure { } tasks.withType().configureEach { - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = JvmTarget.JVM_17 kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = JvmTarget.JVM_17 } } @@ -79,10 +87,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 { group = "verification" description = "Runs the System tests" 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 d3d66c469b7..3c7e00ae552 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 @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.tasks.run.BootRun @@ -19,6 +20,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" @@ -27,14 +34,12 @@ configure { targetCompatibility = JavaVersion.VERSION_17 } -tasks.withType().configureEach { - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 -} +tasks.withType().configureEach { compilerOptions.jvmTarget = JvmTarget.JVM_17 } tasks.withType().configureEach { kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = JvmTarget.JVM_17 } } @@ -83,8 +88,6 @@ dependencies { testImplementation("ch.qos.logback:logback-core:1.5.16") } -configure { test { java.srcDir("src/test/java") } } - tasks.register("bootRunWithAgent").configure { group = "application" 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 ae3ef70ad70..d5e4caa595d 100644 --- a/sentry-samples/sentry-samples-spring-boot-jakarta/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-jakarta/build.gradle.kts @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -18,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" @@ -26,14 +33,12 @@ configure { targetCompatibility = JavaVersion.VERSION_17 } -tasks.withType().configureEach { - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 -} +tasks.withType().configureEach { compilerOptions.jvmTarget = JvmTarget.JVM_17 } tasks.withType().configureEach { kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = JvmTarget.JVM_17 } } @@ -85,8 +90,6 @@ dependencies { testImplementation("ch.qos.logback:logback-core:1.5.16") } -configure { test { java.srcDir("src/test/java") } } - tasks.register("systemTest").configure { group = "verification" description = "Runs the System tests" 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 f1665f513d1..0b8c5a181e7 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 @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -15,25 +16,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() } -configure { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 +fun springBoot2SupportsOptionalIntegrations(): 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) } -tasks.withType().configureEach { - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 +val includeGraphql = + !project.hasProperty("excludeGraphql") && springBoot2SupportsOptionalIntegrations() +val includeKafka = !project.hasProperty("excludeKafka") && springBoot2SupportsOptionalIntegrations() + +configure { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } +tasks.withType().configureEach { compilerOptions.jvmTarget = JvmTarget.JVM_11 } + tasks.withType().configureEach { kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = JvmTarget.JVM_11 } } @@ -43,7 +54,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,14 +68,17 @@ 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) - // kafka - implementation(libs.spring.kafka2) - implementation(projects.sentryKafka) + if (includeKafka) { + implementation(libs.spring.kafka2) + implementation(projects.sentryKafka) + } // database query tracing implementation(projects.sentryJdbc) @@ -103,7 +119,18 @@ tasks.jar { tasks.startScripts { dependsOn(tasks.shadowJar) } -configure { test { java.srcDir("src/test/java") } } +configure { + main { + if (!includeGraphql) { + java.exclude("**/graphql/**") + resources.exclude("graphql/**") + } + if (!includeKafka) { + java.exclude("**/queues/kafka/**") + resources.exclude("application-kafka.properties") + } + } +} tasks.register("systemTest").configure { group = "verification" @@ -121,7 +148,15 @@ 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*") + } + if (!includeKafka) { + excludeTestsMatching("io.sentry.systemtest.Kafka*") + } + } } 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 7c84875ca07..b78f1f01881 100644 --- a/sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -15,22 +16,34 @@ 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 springBoot2SupportsOptionalIntegrations(): 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") && springBoot2SupportsOptionalIntegrations() +val includeKafka = !project.hasProperty("excludeKafka") && springBoot2SupportsOptionalIntegrations() + 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 = JvmTarget.JVM_11 kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = JvmTarget.JVM_11 } } @@ -39,7 +52,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,14 +66,17 @@ 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) - // kafka - implementation(libs.spring.kafka2) - implementation(projects.sentryKafka) + if (includeKafka) { + implementation(libs.spring.kafka2) + implementation(projects.sentryKafka) + } // database query tracing implementation(projects.sentryJdbc) @@ -99,7 +117,18 @@ tasks.jar { tasks.startScripts { dependsOn(tasks.shadowJar) } -configure { test { java.srcDir("src/test/java") } } +configure { + main { + if (!includeGraphql) { + java.exclude("**/graphql/**") + resources.exclude("graphql/**") + } + if (!includeKafka) { + java.exclude("**/queues/kafka/**") + resources.exclude("application-kafka.properties") + } + } +} tasks.register("bootRunWithAgent").configure { group = "application" @@ -141,7 +170,15 @@ 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*") + } + if (!includeKafka) { + excludeTestsMatching("io.sentry.systemtest.Kafka*") + } + } } 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 d5b04543576..8b2079ddd9c 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 @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -18,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" @@ -50,12 +57,10 @@ dependencies { testImplementation("ch.qos.logback:logback-core:1.5.16") } -configure { 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 = JvmTarget.JVM_17 } } 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 b10b30737d8..2127dbfd79f 100644 --- a/sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -15,22 +16,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 +83,19 @@ tasks.jar { tasks.startScripts { dependsOn(tasks.shadowJar) } -configure { test { java.srcDir("src/test/java") } } +configure { + main { + if (!includeGraphql) { + java.exclude("**/graphql/**") + resources.exclude("graphql/**") + } + } +} tasks.withType().configureEach { kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = 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 cd69d854006..4bd6bb77bfb 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 ed7422d9d0b..4a9ae98a447 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 @@ -4,14 +4,12 @@ import java.time.Duration; import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; -import reactor.core.scheduler.Schedulers; @Service public class PersonService { Mono create(Person person) { return Mono.delay(Duration.ofMillis(100)) - .publishOn(Schedulers.boundedElastic()) .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 cc535c725e1..0a2a6f2da57 100644 --- a/sentry-samples/sentry-samples-spring-boot/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-boot/build.gradle.kts @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -15,21 +16,33 @@ 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 springBoot2SupportsOptionalIntegrations(): 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") && springBoot2SupportsOptionalIntegrations() +val includeKafka = !project.hasProperty("excludeKafka") && springBoot2SupportsOptionalIntegrations() + 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 = JvmTarget.JVM_11 } } @@ -38,7 +51,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) @@ -48,15 +63,18 @@ dependencies { implementation(libs.springboot.starter.websocket) implementation(libs.caffeine) - // kafka - implementation(libs.spring.kafka2) - implementation(projects.sentryKafka) + if (includeKafka) { + implementation(libs.spring.kafka2) + implementation(projects.sentryKafka) + } implementation(Config.Libs.aspectj) 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.sentryQuartz) implementation(projects.sentryAsyncProfiler) @@ -102,7 +120,18 @@ tasks.jar { tasks.startScripts { dependsOn(tasks.shadowJar) } -configure { test { java.srcDir("src/test/java") } } +configure { + main { + if (!includeGraphql) { + java.exclude("**/graphql/**") + resources.exclude("graphql/**") + } + if (!includeKafka) { + java.exclude("**/queues/kafka/**") + resources.exclude("application-kafka.properties") + } + } +} tasks.register("systemTest").configure { group = "verification" @@ -120,7 +149,15 @@ 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*") + } + if (!includeKafka) { + excludeTestsMatching("io.sentry.systemtest.Kafka*") + } + } } 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 319431e71d2..3dec793e5c9 100644 --- a/sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts @@ -1,9 +1,8 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget 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,8 +30,9 @@ 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()) + mavenBom(libs.jackson.bom.get().toString()) } } @@ -57,7 +57,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") } } @@ -65,12 +65,10 @@ dependencies { tasks.withType().configureEach { kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + compilerOptions.jvmTarget = JvmTarget.JVM_17 } } -configure { test { java.srcDir("src/test/java") } } - tasks.register("systemTest").configure { group = "verification" description = "Runs the System tests" diff --git a/sentry-samples/sentry-samples-spring/build.gradle.kts b/sentry-samples/sentry-samples-spring/build.gradle.kts index 446baf3a696..02e7f632450 100644 --- a/sentry-samples/sentry-samples-spring/build.gradle.kts +++ b/sentry-samples/sentry-samples-spring/build.gradle.kts @@ -1,3 +1,4 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -33,6 +34,7 @@ dependencyManagement { mavenBom(libs.springboot2.bom.get().toString()) mavenBom(libs.kotlin.bom.get().toString()) mavenBom(libs.jackson.bom.get().toString()) + mavenBom(libs.okhttp.bom.get().toString()) } } @@ -64,12 +66,10 @@ dependencies { tasks.withType().configureEach { kotlin { compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict") - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8 + compilerOptions.jvmTarget = JvmTarget.JVM_1_8 } } -configure { test { java.srcDir("src/test/java") } } - tasks.register("systemTest").configure { group = "verification" description = "Runs the System tests" diff --git a/sentry-spring-boot/build.gradle.kts b/sentry-spring-boot/build.gradle.kts index 74f5d7c87bb..e54112ae54c 100644 --- a/sentry-spring-boot/build.gradle.kts +++ b/sentry-spring-boot/build.gradle.kts @@ -1,4 +1,5 @@ import net.ltgt.gradle.errorprone.errorprone +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -12,7 +13,7 @@ plugins { } tasks.withType().configureEach { - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8 + compilerOptions.jvmTarget = JvmTarget.JVM_1_8 compilerOptions.languageVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9 compilerOptions.apiVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9 } @@ -35,7 +36,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(libs.spring.kafka2) @@ -84,8 +85,6 @@ dependencies { testImplementation(projects.sentryAsyncProfiler) } -configure { test { java.srcDir("src/test/java") } } - jacoco { toolVersion = libs.versions.jacoco.get() } tasks.jacocoTestReport { 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 c7d5a892e9f..f89f5c5bb31 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; @@ -75,7 +73,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; @@ -203,11 +200,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 1cbcb4f090c..2da1a3dd8d9 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-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java index a75aa281349..4e7c3665aae 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryBatchLoaderRegistry.java @@ -75,8 +75,8 @@ public BatchLoaderRegistry.RegistrationSpec withName(String name) { } @Override - public BatchLoaderRegistry.RegistrationSpec withOptions( - Consumer optionsConsumer) { + @SuppressWarnings({"rawtypes", "unchecked"}) + public BatchLoaderRegistry.RegistrationSpec withOptions(Consumer optionsConsumer) { return delegate.withOptions(optionsConsumer); } diff --git a/sentry-spring/build.gradle.kts b/sentry-spring/build.gradle.kts index c4c75cb5f07..64380f7e7f4 100644 --- a/sentry-spring/build.gradle.kts +++ b/sentry-spring/build.gradle.kts @@ -1,4 +1,5 @@ import net.ltgt.gradle.errorprone.errorprone +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -12,7 +13,7 @@ plugins { } tasks.withType().configureEach { - compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8 + compilerOptions.jvmTarget = JvmTarget.JVM_1_8 compilerOptions.languageVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9 compilerOptions.apiVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9 } @@ -34,7 +35,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(libs.spring.kafka2) compileOnly(projects.sentryOpentelemetry.sentryOpentelemetryAgentcustomization) @@ -63,8 +64,6 @@ dependencies { testImplementation(libs.springboot.starter.webflux) } -configure { test { java.srcDir("src/test/java") } } - jacoco { toolVersion = libs.versions.jacoco.get() } tasks.jacocoTestReport { diff --git a/test/system-test-runner.py b/test/system-test-runner.py index 784448715e9..7dd7530c8bd 100644 --- a/test/system-test-runner.py +++ b/test/system-test-runner.py @@ -224,11 +224,14 @@ def kill_process(self, pid: int, name: str) -> None: except (OSError, ProcessLookupError): print(f"Process {pid} was already dead") + def exclude_kafka(self) -> bool: + return os.environ.get("ORG_GRADLE_PROJECT_excludeKafka") == "true" + def module_requires_kafka(self, sample_module: str) -> bool: - return sample_module in KAFKA_BROKER_REQUIRED_MODULES + return not self.exclude_kafka() and sample_module in KAFKA_BROKER_REQUIRED_MODULES def module_requires_kafka_profile(self, sample_module: str) -> bool: - return sample_module in KAFKA_PROFILE_REQUIRED_MODULES + return not self.exclude_kafka() and sample_module in KAFKA_PROFILE_REQUIRED_MODULES def wait_for_port(self, host: str, port: int, max_attempts: int = 20) -> bool: for _ in range(max_attempts):