This is an automated email from the ASF dual-hosted git repository.

gaogaotiantian pushed a commit to branch branch-4.x
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-4.x by this push:
     new 1e85654c7306 [SPARK-57540][SQL] Instantiate Woodstox 
`WstxOutputFactory` directly in `StaxXmlGenerator`
1e85654c7306 is described below

commit 1e85654c730688a2dde77b5b9ded500d94376bb6
Author: Tian Gao <[email protected]>
AuthorDate: Mon Jun 22 13:11:22 2026 -0700

    [SPARK-57540][SQL] Instantiate Woodstox `WstxOutputFactory` directly in 
`StaxXmlGenerator`
    
    ### What changes were proposed in this pull request?
    
    In `StaxXmlGenerator`, the StAX `XMLOutputFactory` was obtained via 
`XMLOutputFactory.newInstance()` and then configured with Woodstox-specific 
properties from the shaded Hadoop Woodstox 
(`org.apache.hadoop.shaded.com.ctc.wstx.api.WstxOutputProperties`).
    
    This PR constructs the shaded Woodstox factory directly:
    
    ```scala
    val factory = new 
org.apache.hadoop.shaded.com.ctc.wstx.stax.WstxOutputFactory()
    ```
    
    instead of relying on `XMLOutputFactory.newInstance()`.
    
    ### Why are the changes needed?
    
    `XMLOutputFactory.newInstance()` resolves a concrete StAX implementation 
through the JAXP/service-loader lookup. If any other (unshaded) StAX provider 
happens to be on the classpath, it can win that lookup and return a factory 
that is **not** the shaded Woodstox. That factory does not understand the 
shaded `WstxOutputProperties.P_OUTPUT_VALIDATE_STRUCTURE` / 
`P_OUTPUT_VALIDATE_NAMES` keys set immediately afterwards, and Woodstox/StAX 
throws `IllegalArgumentException` for unknown prope [...]
    
    By instantiating the shaded `WstxOutputFactory` directly, the factory 
implementation and the property keys are guaranteed to come from the same 
shaded Woodstox, eliminating the potential conflict regardless of what else is 
on the classpath.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    Existing `to_xml` / XML write tests in `XmlSuite` cover this code path. No 
behavior change is expected; the factory used is the same shaded Woodstox that 
the configured properties already targeted.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 4.8)
    
    Closes #56600 from gaogaotiantian/SPARK-wstx-output-factory.
    
    Authored-by: Tian Gao <[email protected]>
    Signed-off-by: Tian Gao <[email protected]>
    (cherry picked from commit 13dac20283ce7b0c682ed954f908cc3e725a69bb)
    Signed-off-by: Tian Gao <[email protected]>
---
 .../org/apache/spark/sql/catalyst/xml/StaxXmlGenerator.scala   | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/xml/StaxXmlGenerator.scala
 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/xml/StaxXmlGenerator.scala
index 2a08a2e4d4b5..6e381a2974c7 100644
--- 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/xml/StaxXmlGenerator.scala
+++ 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/xml/StaxXmlGenerator.scala
@@ -19,11 +19,11 @@ package org.apache.spark.sql.catalyst.xml
 import java.io.Writer
 import java.sql.Timestamp
 import java.util.Base64
-import javax.xml.stream.XMLOutputFactory
 
 import scala.collection.Map
 
 import org.apache.hadoop.shaded.com.ctc.wstx.api.WstxOutputProperties
+import org.apache.hadoop.shaded.com.ctc.wstx.stax.WstxOutputFactory
 
 import org.apache.spark.SparkIllegalArgumentException
 import org.apache.spark.sql.catalyst.InternalRow
@@ -72,7 +72,13 @@ class StaxXmlGenerator(
   private val binaryFormatter = ToStringBase.getBinaryFormatter
 
   private val gen = {
-    val factory = XMLOutputFactory.newInstance()
+    // Instantiate the Woodstox factory directly from the shaded Hadoop 
classes instead of
+    // using XMLOutputFactory.newInstance(). The latter resolves an 
implementation via the
+    // service-loader mechanism, which could pick up a different (unshaded) 
StAX provider on the
+    // classpath. Such a provider would not understand the shaded 
WstxOutputProperties keys set
+    // below and would throw IllegalArgumentException. Constructing the shaded 
factory directly
+    // guarantees the properties and the implementation always match.
+    val factory = new WstxOutputFactory()
     // to_xml disables structure validation to allow multiple root tags
     factory.setProperty(WstxOutputProperties.P_OUTPUT_VALIDATE_STRUCTURE, 
validateStructure)
     factory.setProperty(WstxOutputProperties.P_OUTPUT_VALIDATE_NAMES, 
options.validateName)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to