Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
055a019
fix(build): remove Spring Boot 2 Gradle plugin for Gradle 9 compatibiโ€ฆ
adinauer Apr 2, 2026
9dd4f2f
fix: set duplicatesStrategy=INCLUDE for shadow JAR spring.factories mโ€ฆ
adinauer Apr 2, 2026
63aa458
fix: remove duplicate shadow plugin entry in version catalog
adinauer Apr 2, 2026
0e43fc7
Format code
getsentry-bot Apr 2, 2026
da7d400
fix: update system test runner for shadow JAR compatibility
adinauer Apr 2, 2026
c0acbd7
fix(otel): use DuplicatesStrategy.INCLUDE for otel agent shadow JAR
adinauer Apr 2, 2026
c3c8c24
Exclude test-support modules from api validation
romtsn Apr 7, 2026
76eba12
Verbose system test output and wire inputs for them properly
romtsn Apr 7, 2026
5bfc096
align coroutines version to 1.9.0 for system tests
romtsn Apr 7, 2026
5a29bc6
fix(otel): use mergeServiceFiles path instead of include for Shadow 9.x
romtsn Apr 10, 2026
f47be74
fix(otel): add default mergeServiceFiles for bootstrap service relocaโ€ฆ
romtsn Apr 10, 2026
00c8173
fix(spring-boot2): pre-merge Spring metadata for Shadow 9.x compatibiโ€ฆ
romtsn Apr 10, 2026
3bfe40d
Format code
getsentry-bot Apr 10, 2026
0a95998
fix(lint): suppress OldTargetApi for uitest-android module
romtsn Apr 10, 2026
9a388af
fix(spring-boot2): make mergeSpringMetadata configuration-cache compaโ€ฆ
romtsn Apr 10, 2026
8ae3c9c
formatting
romtsn Apr 10, 2026
4a48a27
fix(spring-boot2): replace from() with doLast JAR patching for springโ€ฆ
romtsn Apr 10, 2026
05c5bac
formatting
romtsn Apr 10, 2026
4bef2eb
fix(spring-boot2): merge AutoConfiguration.imports + doLast JAR patching
romtsn Apr 10, 2026
9fa7649
fix(spring-boot2): also merge ManagementContextConfiguration.imports
romtsn Apr 10, 2026
4a277ae
formatting
romtsn Apr 10, 2026
991221e
fix(spring-boot2): use separate patchSpringMetadata task for JAR patcโ€ฆ
romtsn Apr 10, 2026
500f7f1
formatting
romtsn Apr 10, 2026
cafc487
fix(spring-boot2): revert to doLast on shadowJar for Spring metadata โ€ฆ
romtsn Apr 11, 2026
702dfd0
formatting
romtsn Apr 11, 2026
821da53
fix(spring-boot2): inline Spring metadata merge into shadowJar doLast
romtsn Apr 11, 2026
b8ec4e1
Format code
getsentry-bot Apr 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ apiValidation {
"test-app-sentry",
"test-app-size",
"sentry-samples-netflix-dgs",
"sentry-samples-console-otlp"
"sentry-samples-console-otlp",
"sentry-test-support",
"sentry-system-test-support"
)
)
}
Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,13 @@ 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" }
springboot2 = { id = "org.springframework.boot", version.ref = "springboot2" }
springboot3 = { id = "org.springframework.boot", version.ref = "springboot3" }
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" }
animalsniffer = { id = "ru.vyarus.animalsniffer", version = "2.0.1" }
sentry = { id = "io.sentry.android.gradle", version = "6.0.0-alpha.6"}
shadow = { id = "com.gradleup.shadow", version = "8.3.6" }
shadow = { id = "com.gradleup.shadow", version = "9.4.1" }

[libraries]
apache-httpclient = { module = "org.apache.httpcomponents.client5:httpclient5", version = "5.0.4" }
Expand Down Expand Up @@ -159,6 +158,7 @@ slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
slf4j-jdk14 = { module = "org.slf4j:slf4j-jdk14", version.ref = "slf4j" }
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" }
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" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ android {
lint {
warningsAsErrors = true
checkDependencies = true
// Suppress OldTargetApi: lint 8.13.1 expects API 37 but we target 36
disable += "OldTargetApi"

// We run a full lint analysis as build part in CI, so skip vital checks for assemble tasks.
checkReleaseBuilds = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ android {
lint {
warningsAsErrors = true
checkDependencies = true
// Suppress OldTargetApi: lint 8.13.1 expects API 37 but we target 36
disable += "OldTargetApi"

// We run a full lint analysis as build part in CI, so skip vital checks for assemble tasks.
checkReleaseBuilds = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,22 @@ tasks {

archiveClassifier.set("")

duplicatesStrategy = DuplicatesStrategy.FAIL

mergeServiceFiles { include("inst/META-INF/services/*") }
// INCLUDE is required so that mergeServiceFiles can see duplicates from both the
// upstream agent JAR and the isolated distro libs before they are deduplicated.
// Shadow 9.x enforces duplicatesStrategy before transformers run, so FAIL/EXCLUDE
// would prevent service file merging.
duplicatesStrategy = DuplicatesStrategy.INCLUDE

// Shadow 9.x only applies relocations to service files handled by a ServiceFileTransformer.
// We need two mergeServiceFiles calls:
// 1. Default path (META-INF/services) โ€” ensures bootstrap service files get relocated
// (e.g., ContextStorageProvider โ†’ shaded path). Without this, Shadow 9.x skips
// relocation for service file names/contents not claimed by a transformer.
// 2. inst/ path โ€” merges isolated agent service files from both the upstream agent
// and the distro libs. Uses `path` instead of `include` filter because Shadow 9.x's
// include() strips the `inst/` prefix on output.
mergeServiceFiles()
mergeServiceFiles { path = "inst/META-INF/services" }
exclude("**/module-info.class")
relocatePackages(this)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ dependencies {
tasks.shadowJar {
manifest { attributes["Main-Class"] = "io.sentry.samples.console.Main" }
archiveClassifier.set("") // Remove the classifier so it replaces the regular JAR
duplicatesStrategy = DuplicatesStrategy.INCLUDE
mergeServiceFiles()
}

Expand All @@ -66,6 +67,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
5 changes: 5 additions & 0 deletions sentry-samples/sentry-samples-console-otlp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ dependencies {
tasks.shadowJar {
manifest { attributes["Main-Class"] = "io.sentry.samples.console.Main" }
archiveClassifier.set("") // Remove the classifier so it replaces the regular JAR
duplicatesStrategy = DuplicatesStrategy.INCLUDE
mergeServiceFiles()
}

Expand All @@ -69,6 +70,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
4 changes: 4 additions & 0 deletions sentry-samples/sentry-samples-console/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
4 changes: 4 additions & 0 deletions sentry-samples/sentry-samples-jul/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
5 changes: 5 additions & 0 deletions sentry-samples/sentry-samples-log4j2/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ dependencies {
tasks.shadowJar {
manifest { attributes["Main-Class"] = "io.sentry.samples.log4j2.Main" }
archiveClassifier.set("") // Remove the classifier so it replaces the regular JAR
duplicatesStrategy = DuplicatesStrategy.INCLUDE
mergeServiceFiles()
// Use Log4j2 cache transformer to properly handle plugin files
transform(
Expand All @@ -67,6 +68,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
4 changes: 4 additions & 0 deletions sentry-samples/sentry-samples-logback/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
68 changes: 66 additions & 2 deletions sentry-samples/sentry-samples-netflix-dgs/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import java.net.URI
import java.nio.file.FileSystems
import java.nio.file.Files
import java.util.zip.ZipFile
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
alias(libs.plugins.springboot2)
alias(libs.plugins.spring.dependency.management)
java
application
alias(libs.plugins.shadow)
alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.kotlin.spring)
}

application { mainClass.set("io.sentry.samples.netflix.dgs.NetlixDgsApplication") }

group = "io.sentry.sample.spring-boot"

version = "0.0.1-SNAPSHOT"
Expand All @@ -19,6 +26,7 @@ java.targetCompatibility = JavaVersion.VERSION_1_8
repositories { mavenCentral() }

dependencies {
implementation(platform(libs.springboot2.bom))
implementation(libs.springboot.starter.web)
implementation(Config.Libs.kotlinReflect)
implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION))
Expand All @@ -32,6 +40,62 @@ dependencies {
}
}

// Configure the Shadow JAR (executable JAR with all dependencies)
tasks.shadowJar {
manifest { attributes["Main-Class"] = "io.sentry.samples.netflix.dgs.NetlixDgsApplication" }
archiveClassifier.set("")
mergeServiceFiles()

val springMetadataFiles =
listOf(
"META-INF/spring.factories",
"META-INF/spring.handlers",
"META-INF/spring.schemas",
"META-INF/spring-autoconfigure-metadata.properties",
"META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
"META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports",
)

doLast {
val jar = archiveFile.get().asFile
val runtimeJars =
project.configurations.getByName("runtimeClasspath").resolve().filter {
it.name.endsWith(".jar")
}
val uri = URI.create("jar:${jar.toURI()}")
FileSystems.newFileSystem(uri, mapOf("create" to "false")).use { fs ->
springMetadataFiles.forEach { entryPath ->
val merged = StringBuilder()
runtimeJars.forEach { depJar ->
try {
val zip = ZipFile(depJar)
val entry = zip.getEntry(entryPath)
if (entry != null) {
merged.append(zip.getInputStream(entry).bufferedReader().readText())
if (!merged.endsWith("\n")) merged.append("\n")
}
zip.close()
} catch (e: Exception) {
/* skip non-zip files */
}
}
if (merged.isNotEmpty()) {
val target = fs.getPath(entryPath)
if (target.parent != null) Files.createDirectories(target.parent)
Files.write(target, merged.toString().toByteArray())
}
}
}
}
}

tasks.jar {
enabled = false
dependsOn(tasks.shadowJar)
}

tasks.startScripts { dependsOn(tasks.shadowJar) }

tasks.withType<Test>().configureEach { useJUnitPlatform() }

tasks.withType<KotlinCompile>().configureEach {
Expand Down
4 changes: 4 additions & 0 deletions sentry-samples/sentry-samples-spring-7/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ java.targetCompatibility = JavaVersion.VERSION_17

repositories { mavenCentral() }

// Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version
extra["kotlin-coroutines.version"] = "1.9.0"

configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
Expand Down Expand Up @@ -80,6 +83,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ java.targetCompatibility = JavaVersion.VERSION_17

repositories { mavenCentral() }

// Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version
extra["kotlin-coroutines.version"] = "1.9.0"

configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
Expand Down Expand Up @@ -114,6 +117,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ java.targetCompatibility = JavaVersion.VERSION_17

repositories { mavenCentral() }

// Apollo 4.x requires coroutines 1.9.0+, override Spring Boot's managed version
extra["kotlin-coroutines.version"] = "1.9.0"

configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
Expand Down Expand Up @@ -69,7 +72,6 @@ dependencies {
testImplementation(kotlin(Config.kotlinStdLib))
testImplementation(projects.sentry)
testImplementation(projects.sentrySystemTestSupport)
testImplementation(libs.apollo3.kotlin)
testImplementation(libs.kotlin.test.junit)
testImplementation(libs.slf4j2.api)
testImplementation(libs.springboot3.starter.test) {
Expand All @@ -85,6 +87,10 @@ tasks.register<Test>("systemTest").configure {
group = "verification"
description = "Runs the System tests"

val test = project.extensions.getByType<SourceSetContainer>()["test"]
testClassesDirs = test.output.classesDirs
classpath = test.runtimeClasspath

outputs.upToDateWhen { false }

maxParallelForks = 1
Expand Down
Loading