You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by lh...@apache.org on 2026/08/14 13:12:16 UTC
(pulsar) branch master updated: [improve][build] Upgrade Shadow plugin to 9.6.1 and merge service descriptor files in shaded jars (#26333)
This is an automated email from the ASF dual-hosted git repository.
lhotari pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/master by this push:
new b0a260471fb2 [improve][build] Upgrade Shadow plugin to 9.6.1 and merge service descriptor files in shaded jars (#26333)
b0a260471fb2 is described below
commit b0a260471fb23ea9e7d0a7ab38aa26f621d94aea
Author: Lari Hotari <lh...@users.noreply.github.com>
AuthorDate: Fri Aug 14 16:12:11 2026 +0300
[improve][build] Upgrade Shadow plugin to 9.6.1 and merge service descriptor files in shaded jars (#26333)
---
build-logic/conventions/build.gradle.kts | 3 +++
.../main/kotlin/pulsar.shadow-conventions.gradle.kts | 17 +++++++++++++++++
gradle/libs.versions.toml | 2 +-
microbench/build.gradle.kts | 7 +++++++
pulsar-functions/runtime-all/build.gradle.kts | 7 +++++++
5 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/build-logic/conventions/build.gradle.kts b/build-logic/conventions/build.gradle.kts
index bc3d07a2be5d..46120a3102ed 100644
--- a/build-logic/conventions/build.gradle.kts
+++ b/build-logic/conventions/build.gradle.kts
@@ -22,6 +22,9 @@ plugins {
}
dependencies {
+ // The Shadow plugin brings its own log4j-core onto the build classpath; align it with the
+ // log4j version the rest of the build uses (`log4j2` in the version catalog).
+ implementation(platform(libs.log4j.bom))
implementation(libs.plugins.shadow.get().let {
"${it.pluginId}:${it.pluginId}.gradle.plugin:${it.version}"
})
diff --git a/build-logic/conventions/src/main/kotlin/pulsar.shadow-conventions.gradle.kts b/build-logic/conventions/src/main/kotlin/pulsar.shadow-conventions.gradle.kts
index 7a760e58e818..9864c439d630 100644
--- a/build-logic/conventions/src/main/kotlin/pulsar.shadow-conventions.gradle.kts
+++ b/build-logic/conventions/src/main/kotlin/pulsar.shadow-conventions.gradle.kts
@@ -32,7 +32,24 @@ shadow {
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
archiveClassifier.set("")
+ // ShadowJar's duplicatesStrategy is applied *before* the resource transformers run, so its
+ // EXCLUDE default drops every duplicate META-INF/services file and mergeServiceFiles() ends up
+ // keeping only the first provider file instead of merging them all. Keep EXCLUDE as the global
+ // strategy — class files bypass the transformers entirely (ShadowCopyAction handles them in a
+ // dedicated branch), so the strategy is the only thing deduplicating them — and let just the
+ // service descriptors through to the transformer.
mergeServiceFiles()
+ // Paths owned by a resource transformer: ServiceFileTransformer (mergeServiceFiles) and the
+ // KotlinModuleMetadataTransformer that ShadowJar applies on its own.
+ val transformedPaths = listOf("META-INF/services/**", "META-INF/*.kotlin_module")
+ filesMatching(transformedPaths) {
+ duplicatesStrategy = DuplicatesStrategy.INCLUDE
+ }
+ // filesMatching {} actions are not part of the task's input fingerprint, so without this the
+ // build cache serves jars built under the old behaviour even after this block changes.
+ inputs.property("transformedPathsDuplicatesStrategy", "$transformedPaths=INCLUDE")
+ // Nothing should reach the archive twice; catch it if a future change makes it happen.
+ failOnDuplicateEntries.set(true)
}
tasks.named<Jar>("jar") {
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 9453c4459ace..9283cb3b6d97 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -177,7 +177,7 @@ thrift = "0.23.0"
datasketches-memory = "4.1.0"
datasketches-java = "7.0.1"
# Shading
-shadow = "9.4.2"
+shadow = "9.6.1"
[libraries]
# SLF4J
diff --git a/microbench/build.gradle.kts b/microbench/build.gradle.kts
index 216486255c48..ab3a83b3b480 100644
--- a/microbench/build.gradle.kts
+++ b/microbench/build.gradle.kts
@@ -44,6 +44,13 @@ tasks.shadowJar {
archiveClassifier.set("benchmarks")
isZip64 = true
mergeServiceFiles()
+ // See pulsar.shadow-conventions: the default EXCLUDE strategy drops duplicates of
+ // transformer-owned paths before the transformers can merge them.
+ val transformedPaths = listOf("META-INF/services/**", "META-INF/*.kotlin_module")
+ filesMatching(transformedPaths) {
+ duplicatesStrategy = DuplicatesStrategy.INCLUDE
+ }
+ inputs.property("transformedPathsDuplicatesStrategy", "$transformedPaths=INCLUDE")
exclude("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA")
manifest {
attributes("Main-Class" to "org.openjdk.jmh.Main")
diff --git a/pulsar-functions/runtime-all/build.gradle.kts b/pulsar-functions/runtime-all/build.gradle.kts
index 0f7d3ccc368d..5967f1efbae6 100644
--- a/pulsar-functions/runtime-all/build.gradle.kts
+++ b/pulsar-functions/runtime-all/build.gradle.kts
@@ -44,6 +44,13 @@ dependencies {
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
archiveFileName.set("java-instance.jar")
mergeServiceFiles()
+ // See pulsar.shadow-conventions: the default EXCLUDE strategy drops duplicates of
+ // transformer-owned paths before the transformers can merge them.
+ val transformedPaths = listOf("META-INF/services/**", "META-INF/*.kotlin_module")
+ filesMatching(transformedPaths) {
+ duplicatesStrategy = DuplicatesStrategy.INCLUDE
+ }
+ inputs.property("transformedPathsDuplicatesStrategy", "$transformedPaths=INCLUDE")
exclude("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA")
}