Skip to content

Commit cafc487

Browse files
romtsnclaude
andcommitted
fix(spring-boot2): revert to doLast on shadowJar for Spring metadata patching
The separate patchSpringMetadata task approach caused regressions — the finalizedBy relationship didn't reliably execute the patching in CI. Revert to doLast directly on shadowJar with outputs.upToDateWhen { false } to ensure the patching always runs. Also use walkTopDown for recursive directory traversal (needed for META-INF/spring/ subdirectory). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 500f7f1 commit cafc487

File tree

5 files changed

+43
-94
lines changed

5 files changed

+43
-94
lines changed

sentry-samples/sentry-samples-netflix-dgs/build.gradle.kts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,34 +87,24 @@ val mergeSpringMetadata by
8787

8888
// Configure the Shadow JAR (executable JAR with all dependencies)
8989
tasks.shadowJar {
90+
dependsOn(mergeSpringMetadata)
9091
manifest { attributes["Main-Class"] = "io.sentry.samples.netflix.dgs.NetlixDgsApplication" }
9192
archiveClassifier.set("")
9293
mergeServiceFiles()
9394
outputs.upToDateWhen { false }
94-
finalizedBy("patchSpringMetadata")
95-
}
96-
97-
tasks.register("patchSpringMetadata") {
98-
dependsOn(mergeSpringMetadata, tasks.shadowJar)
9995
val metadataDir = project.layout.buildDirectory.dir("merged-spring-metadata")
100-
val jarFile = tasks.shadowJar.flatMap { it.archiveFile }
101-
inputs.dir(metadataDir)
102-
inputs.file(jarFile)
10396
doLast {
10497
val baseDir = metadataDir.get().asFile
105-
val jar = jarFile.get().asFile
98+
val jar = archiveFile.get().asFile
10699
if (!baseDir.exists()) return@doLast
107100
val uri = URI.create("jar:${jar.toURI()}")
108101
FileSystems.newFileSystem(uri, mapOf("create" to "false")).use { fs ->
109-
baseDir
110-
.walkTopDown()
111-
.filter { it.isFile }
112-
.forEach { merged ->
113-
val relative = merged.relativeTo(baseDir).path
114-
val target = fs.getPath(relative)
115-
if (target.parent != null) Files.createDirectories(target.parent)
116-
Files.copy(merged.toPath(), target, StandardCopyOption.REPLACE_EXISTING)
117-
}
102+
baseDir.walkTopDown().filter { it.isFile }.forEach { merged ->
103+
val relative = merged.relativeTo(baseDir).path
104+
val target = fs.getPath(relative)
105+
if (target.parent != null) Files.createDirectories(target.parent)
106+
Files.copy(merged.toPath(), target, StandardCopyOption.REPLACE_EXISTING)
107+
}
118108
}
119109
}
120110
}

sentry-samples/sentry-samples-spring-boot-opentelemetry-noagent/build.gradle.kts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -128,34 +128,24 @@ val mergeSpringMetadata by
128128

129129
// Configure the Shadow JAR (executable JAR with all dependencies)
130130
tasks.shadowJar {
131+
dependsOn(mergeSpringMetadata)
131132
manifest { attributes["Main-Class"] = "io.sentry.samples.spring.boot.SentryDemoApplication" }
132133
archiveClassifier.set("")
133134
mergeServiceFiles()
134135
outputs.upToDateWhen { false }
135-
finalizedBy("patchSpringMetadata")
136-
}
137-
138-
tasks.register("patchSpringMetadata") {
139-
dependsOn(mergeSpringMetadata, tasks.shadowJar)
140136
val metadataDir = project.layout.buildDirectory.dir("merged-spring-metadata")
141-
val jarFile = tasks.shadowJar.flatMap { it.archiveFile }
142-
inputs.dir(metadataDir)
143-
inputs.file(jarFile)
144137
doLast {
145138
val baseDir = metadataDir.get().asFile
146-
val jar = jarFile.get().asFile
139+
val jar = archiveFile.get().asFile
147140
if (!baseDir.exists()) return@doLast
148141
val uri = URI.create("jar:${jar.toURI()}")
149142
FileSystems.newFileSystem(uri, mapOf("create" to "false")).use { fs ->
150-
baseDir
151-
.walkTopDown()
152-
.filter { it.isFile }
153-
.forEach { merged ->
154-
val relative = merged.relativeTo(baseDir).path
155-
val target = fs.getPath(relative)
156-
if (target.parent != null) Files.createDirectories(target.parent)
157-
Files.copy(merged.toPath(), target, StandardCopyOption.REPLACE_EXISTING)
158-
}
143+
baseDir.walkTopDown().filter { it.isFile }.forEach { merged ->
144+
val relative = merged.relativeTo(baseDir).path
145+
val target = fs.getPath(relative)
146+
if (target.parent != null) Files.createDirectories(target.parent)
147+
Files.copy(merged.toPath(), target, StandardCopyOption.REPLACE_EXISTING)
148+
}
159149
}
160150
}
161151
}

sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -124,34 +124,24 @@ val mergeSpringMetadata by
124124

125125
// Configure the Shadow JAR (executable JAR with all dependencies)
126126
tasks.shadowJar {
127+
dependsOn(mergeSpringMetadata)
127128
manifest { attributes["Main-Class"] = "io.sentry.samples.spring.boot.SentryDemoApplication" }
128129
archiveClassifier.set("")
129130
mergeServiceFiles()
130131
outputs.upToDateWhen { false }
131-
finalizedBy("patchSpringMetadata")
132-
}
133-
134-
tasks.register("patchSpringMetadata") {
135-
dependsOn(mergeSpringMetadata, tasks.shadowJar)
136132
val metadataDir = project.layout.buildDirectory.dir("merged-spring-metadata")
137-
val jarFile = tasks.shadowJar.flatMap { it.archiveFile }
138-
inputs.dir(metadataDir)
139-
inputs.file(jarFile)
140133
doLast {
141134
val baseDir = metadataDir.get().asFile
142-
val jar = jarFile.get().asFile
135+
val jar = archiveFile.get().asFile
143136
if (!baseDir.exists()) return@doLast
144137
val uri = URI.create("jar:${jar.toURI()}")
145138
FileSystems.newFileSystem(uri, mapOf("create" to "false")).use { fs ->
146-
baseDir
147-
.walkTopDown()
148-
.filter { it.isFile }
149-
.forEach { merged ->
150-
val relative = merged.relativeTo(baseDir).path
151-
val target = fs.getPath(relative)
152-
if (target.parent != null) Files.createDirectories(target.parent)
153-
Files.copy(merged.toPath(), target, StandardCopyOption.REPLACE_EXISTING)
154-
}
139+
baseDir.walkTopDown().filter { it.isFile }.forEach { merged ->
140+
val relative = merged.relativeTo(baseDir).path
141+
val target = fs.getPath(relative)
142+
if (target.parent != null) Files.createDirectories(target.parent)
143+
Files.copy(merged.toPath(), target, StandardCopyOption.REPLACE_EXISTING)
144+
}
155145
}
156146
}
157147
}

sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -97,34 +97,24 @@ val mergeSpringMetadata by
9797

9898
// Configure the Shadow JAR (executable JAR with all dependencies)
9999
tasks.shadowJar {
100+
dependsOn(mergeSpringMetadata)
100101
manifest { attributes["Main-Class"] = "io.sentry.samples.spring.boot.SentryDemoApplication" }
101102
archiveClassifier.set("")
102103
mergeServiceFiles()
103104
outputs.upToDateWhen { false }
104-
finalizedBy("patchSpringMetadata")
105-
}
106-
107-
tasks.register("patchSpringMetadata") {
108-
dependsOn(mergeSpringMetadata, tasks.shadowJar)
109105
val metadataDir = project.layout.buildDirectory.dir("merged-spring-metadata")
110-
val jarFile = tasks.shadowJar.flatMap { it.archiveFile }
111-
inputs.dir(metadataDir)
112-
inputs.file(jarFile)
113106
doLast {
114107
val baseDir = metadataDir.get().asFile
115-
val jar = jarFile.get().asFile
108+
val jar = archiveFile.get().asFile
116109
if (!baseDir.exists()) return@doLast
117110
val uri = URI.create("jar:${jar.toURI()}")
118111
FileSystems.newFileSystem(uri, mapOf("create" to "false")).use { fs ->
119-
baseDir
120-
.walkTopDown()
121-
.filter { it.isFile }
122-
.forEach { merged ->
123-
val relative = merged.relativeTo(baseDir).path
124-
val target = fs.getPath(relative)
125-
if (target.parent != null) Files.createDirectories(target.parent)
126-
Files.copy(merged.toPath(), target, StandardCopyOption.REPLACE_EXISTING)
127-
}
112+
baseDir.walkTopDown().filter { it.isFile }.forEach { merged ->
113+
val relative = merged.relativeTo(baseDir).path
114+
val target = fs.getPath(relative)
115+
if (target.parent != null) Files.createDirectories(target.parent)
116+
Files.copy(merged.toPath(), target, StandardCopyOption.REPLACE_EXISTING)
117+
}
128118
}
129119
}
130120
}

sentry-samples/sentry-samples-spring-boot/build.gradle.kts

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -126,38 +126,27 @@ val mergeSpringMetadata by
126126

127127
// Configure the Shadow JAR (executable JAR with all dependencies)
128128
tasks.shadowJar {
129+
dependsOn(mergeSpringMetadata)
129130
manifest { attributes["Main-Class"] = "io.sentry.samples.spring.boot.SentryDemoApplication" }
130131
archiveClassifier.set("")
131132
mergeServiceFiles()
132-
// Mark as never up-to-date so doLast always runs to patch Spring metadata
133+
// Never up-to-date: ensures doLast always runs to patch Spring metadata.
134+
// Shadow 9.x's `append` transformer doesn't properly merge Spring metadata files
135+
// because DuplicatesStrategy is enforced before transformers run.
133136
outputs.upToDateWhen { false }
134-
finalizedBy("patchSpringMetadata")
135-
}
136-
137-
// Patch the shadow JAR with pre-merged Spring metadata after it's built.
138-
// Shadow 9.x's `append` transformer doesn't properly merge these files because
139-
// DuplicatesStrategy is enforced before transformers run.
140-
tasks.register("patchSpringMetadata") {
141-
dependsOn(mergeSpringMetadata, tasks.shadowJar)
142137
val metadataDir = project.layout.buildDirectory.dir("merged-spring-metadata")
143-
val jarFile = tasks.shadowJar.flatMap { it.archiveFile }
144-
inputs.dir(metadataDir)
145-
inputs.file(jarFile)
146138
doLast {
147139
val baseDir = metadataDir.get().asFile
148-
val jar = jarFile.get().asFile
140+
val jar = archiveFile.get().asFile
149141
if (!baseDir.exists()) return@doLast
150142
val uri = URI.create("jar:${jar.toURI()}")
151143
FileSystems.newFileSystem(uri, mapOf("create" to "false")).use { fs ->
152-
baseDir
153-
.walkTopDown()
154-
.filter { it.isFile }
155-
.forEach { merged ->
156-
val relative = merged.relativeTo(baseDir).path
157-
val target = fs.getPath(relative)
158-
if (target.parent != null) Files.createDirectories(target.parent)
159-
Files.copy(merged.toPath(), target, StandardCopyOption.REPLACE_EXISTING)
160-
}
144+
baseDir.walkTopDown().filter { it.isFile }.forEach { merged ->
145+
val relative = merged.relativeTo(baseDir).path
146+
val target = fs.getPath(relative)
147+
if (target.parent != null) Files.createDirectories(target.parent)
148+
Files.copy(merged.toPath(), target, StandardCopyOption.REPLACE_EXISTING)
149+
}
161150
}
162151
}
163152
}

0 commit comments

Comments
 (0)