From 5da3d2994851641a565679f5b7ccb1015ff30801 Mon Sep 17 00:00:00 2001 From: Asha Pillai Date: Tue, 25 Aug 2026 15:32:43 -0600 Subject: [PATCH 1/2] Remove woodstox-core-asl: it collides with Jackson's woodstox and breaks StAX The ds3-sdk -all (shadow) jar shipped a Woodstox that could not run against the stax2-api packaged beside it, so any use of the StAX *event* API threw: NoSuchMethodError: 'ds3fatjar.org.codehaus.stax2.ri.EmptyIterator ds3fatjar...EmptyIterator.getInstance()' Cause: ds3-sdk declared org.codehaus.woodstox:woodstox-core-asl:4.4.1 while jackson-dataformat-xml already brings com.fasterxml.woodstox:woodstox-core. Both publish classes in com.ctc.wstx.*, so two Woodstox generations were on the classpath. shadowJar merged them and the ASL 4.4.1 classes won, but stax2-api resolved UP to 4.2.1 because the fasterxml woodstox requires it. ASL 4.4.1 is compiled against stax2-api 3.x, where EmptyIterator.getInstance() returns EmptyIterator; in 4.2.1 it returns Iterator. Method resolution matches on the full descriptor including return type, so the call site could not be resolved. Eight shaded Woodstox classes carried that stale expectation (CompactStartElement, SimpleStartElement, BaseStartElement, MergedNsContext, CompactNsContext, InputElementStack, OutputElementBase, EmptyNamespaceContext). Jackson uses the StAX *streaming* API, so the SDK's own tests never touched the broken method and the jar looked healthy. The AWS SDK's XmlDomParser uses the *event* API, and because the -all jar also registers its relocated Woodstox under the standard META-INF/services/javax.xml.stream.* keys it becomes the JVM-wide StAX provider for anything on the same classpath. In BlackPearl that broke S3 target registration outright: DataPlanner's registerS3Target -> S3 connect -> parse response -> NoSuchMethodError -> 500. ds3-sdk 5.4.1 was unaffected because it paired Woodstox 5.0.3 with a matching stax2-api 3.1.4. Dropping the redundant ASL dependency leaves Jackson's woodstox-core 6.5.0 with its matching stax2-api 4.2.1. Verified on the rebuilt -all jar: - StAX event API (StartElement.getAttributes) now works - DS3 XML read semantics unchanged: an absent element and a self-closing both still deserialize to null, and an empty-text element still yields the nil UUID -- byte-identical to the old jar - DS3 XML writing unchanged: - ds3-sdk unit tests: 320 run, 0 failures, 0 errors Co-Authored-By: Claude Opus 5 --- ds3-sdk/build.gradle.kts | 14 +++++++++++++- libs.versions.toml | 2 -- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ds3-sdk/build.gradle.kts b/ds3-sdk/build.gradle.kts index e1afa6e9e..fe222640b 100644 --- a/ds3-sdk/build.gradle.kts +++ b/ds3-sdk/build.gradle.kts @@ -38,7 +38,19 @@ dependencies { implementation(libs.jacksonDataformatXml) implementation(libs.slf4jApi) implementation(libs.findbugs) - implementation(libs.woodstoxCoreAsl) + // NOTE: do not add org.codehaus.woodstox:woodstox-core-asl back here. + // + // jackson-dataformat-xml already brings com.fasterxml.woodstox:woodstox-core with a + // matching stax2-api, and both Woodstox artifacts publish classes in com.ctc.wstx.*. + // Declaring both put two Woodstox generations on the classpath: shadowJar merged them + // (the ASL 4.4.1 classes won), while stax2-api resolved UP to 4.2.1 because the + // fasterxml woodstox requires it. ASL 4.4.1 is compiled against stax2-api 3.x, so + // CompactStartElement.getAttributes() calls + // EmptyIterator.getInstance():EmptyIterator + // which does not exist in stax2-api 4.2.1 (it returns Iterator there). Every + // consumer of the StAX *event* API then died with NoSuchMethodError -- notably the + // AWS SDK's XmlDomParser, which broke S3 target registration in BlackPearl. Jackson + // itself uses the streaming API, so the SDK's own tests never noticed. testImplementation(platform(libs.mockitoBom)) diff --git a/libs.versions.toml b/libs.versions.toml index 3eac4dfdb..58a44d1f6 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -34,7 +34,6 @@ junitVersion = "4.13.2" kotlinVersion = "1.6.10" mockitoVersion = "4.7.0" slf4jVersion = "1.7.36" -woodstoxVersion = "4.4.1" [libraries] commonsCodec = { group = "commons-codec", name = "commons-codec", version.ref = "commonsCodecVersion" } @@ -52,7 +51,6 @@ jnaPlatform = { group = "net.java.dev.jna", name = "jna-platform", version.ref = kotlinStdLib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlinVersion" } ## end kotlin-bom controlled dependencies slf4jApi = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4jVersion" } -woodstoxCoreAsl = { group = "org.codehaus.woodstox", name = "woodstox-core-asl", version.ref = "woodstoxVersion" } # # test only libraries # From 0da92be56097d6f1cc6cc95a69a93aacfd5b850a Mon Sep 17 00:00:00 2001 From: Asha Pillai Date: Tue, 25 Aug 2026 15:36:48 -0600 Subject: [PATCH 2/2] Remove comments Signed-off-by: Asha Pillai --- ds3-sdk/build.gradle.kts | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/ds3-sdk/build.gradle.kts b/ds3-sdk/build.gradle.kts index fe222640b..66da74580 100644 --- a/ds3-sdk/build.gradle.kts +++ b/ds3-sdk/build.gradle.kts @@ -38,19 +38,7 @@ dependencies { implementation(libs.jacksonDataformatXml) implementation(libs.slf4jApi) implementation(libs.findbugs) - // NOTE: do not add org.codehaus.woodstox:woodstox-core-asl back here. - // - // jackson-dataformat-xml already brings com.fasterxml.woodstox:woodstox-core with a - // matching stax2-api, and both Woodstox artifacts publish classes in com.ctc.wstx.*. - // Declaring both put two Woodstox generations on the classpath: shadowJar merged them - // (the ASL 4.4.1 classes won), while stax2-api resolved UP to 4.2.1 because the - // fasterxml woodstox requires it. ASL 4.4.1 is compiled against stax2-api 3.x, so - // CompactStartElement.getAttributes() calls - // EmptyIterator.getInstance():EmptyIterator - // which does not exist in stax2-api 4.2.1 (it returns Iterator there). Every - // consumer of the StAX *event* API then died with NoSuchMethodError -- notably the - // AWS SDK's XmlDomParser, which broke S3 target registration in BlackPearl. Jackson - // itself uses the streaming API, so the SDK's own tests never noticed. + testImplementation(platform(libs.mockitoBom))