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

ppkarwasz pushed a commit to branch feature/reduce-shade-footprint
in repository https://gitbox.apache.org/repos/asf/commons-xml.git

commit a442d1cfd54c969d70150eecebd16c9b63347e2d
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Wed Jul 8 10:29:43 2026 +0200

    Inline the typed JAXP setters into each hardener
    
    Move the setFeature/setOptionalFeature/trySetProperty/trySetAttribute/
    setOptionalAttribute helpers out of the shared JaxpSetters class and into
    the hardener that uses them, as private methods, so shading one hardener
    no longer drags in the setters (and dead overloads) of the others. Only
    the shared "Failed to set ..." message stays central, on
    HardeningException.settingFailed. Delete JaxpSetters.
    
    Cuts the DOM/SAX/StAX shade closures by the whole JaxpSetters class
    (7946 bytes): DocumentBuilderHardener 26225 -> 19265, SAXParserHardener
    32508 -> 25721, StaxHardener 28173 -> 20547 bytes. Update
    ShadingFootprintTest's expected sets accordingly.
    
    Assisted-By: Claude Opus 4.8 <[email protected]>
---
 .../commons/xml/DocumentBuilderHardener.java       |  19 ++-
 .../java/org/apache/commons/xml/JaxpSetters.java   | 151 ---------------------
 .../org/apache/commons/xml/SAXParserHardener.java  |  37 ++++-
 .../java/org/apache/commons/xml/StaxHardener.java  |  14 +-
 .../apache/commons/xml/TransformerHardener.java    |  10 +-
 .../java/org/apache/commons/xml/XPathHardener.java |  19 ++-
 .../apache/commons/xml/ShadingFootprintTest.java   |   7 +-
 7 files changed, 85 insertions(+), 172 deletions(-)

diff --git a/src/main/java/org/apache/commons/xml/DocumentBuilderHardener.java 
b/src/main/java/org/apache/commons/xml/DocumentBuilderHardener.java
index 28150cb..a97af17 100644
--- a/src/main/java/org/apache/commons/xml/DocumentBuilderHardener.java
+++ b/src/main/java/org/apache/commons/xml/DocumentBuilderHardener.java
@@ -17,9 +17,6 @@
 
 package org.apache.commons.xml;
 
-import static org.apache.commons.xml.JaxpSetters.setFeature;
-import static org.apache.commons.xml.JaxpSetters.setOptionalFeature;
-
 import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -66,6 +63,22 @@ static DocumentBuilderFactory harden(final 
DocumentBuilderFactory factory) {
         return new HardeningDocumentBuilderFactory(factory);
     }
 
+    private static void setFeature(final DocumentBuilderFactory factory, final 
String feature, final boolean value) {
+        try {
+            factory.setFeature(feature, value);
+        } catch (final Exception e) {
+            throw HardeningException.settingFailed("feature", feature, 
factory, e);
+        }
+    }
+
+    private static void setOptionalFeature(final DocumentBuilderFactory 
factory, final String feature, final boolean value) {
+        try {
+            factory.setFeature(feature, value);
+        } catch (final Exception e) {
+            // Ignored: the implementation does not recognize this feature.
+        }
+    }
+
     private DocumentBuilderHardener() {
     }
 }
diff --git a/src/main/java/org/apache/commons/xml/JaxpSetters.java 
b/src/main/java/org/apache/commons/xml/JaxpSetters.java
deleted file mode 100644
index 471a3a2..0000000
--- a/src/main/java/org/apache/commons/xml/JaxpSetters.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.commons.xml;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.validation.SchemaFactory;
-import javax.xml.validation.Validator;
-import javax.xml.validation.ValidatorHandler;
-import javax.xml.xpath.XPathFactory;
-
-import org.xml.sax.XMLReader;
-
-/**
- * Setter helpers shared by the bundled hardening providers.
- *
- * <p>Each overload wraps a single JAXP setter (feature, attribute or 
property) in a try/catch that translates any thrown exception into a
- * {@link HardeningException} whose message names the offending feature, 
attribute or property and the concrete factory class.</p>
- */
-final class JaxpSetters {
-
-    /** Action that may throw any exception; used to share a single try/catch 
around every JAXP setter. */
-    @FunctionalInterface
-    private interface ThrowingAction {
-        void run() throws Exception;
-    }
-
-    private static final String KIND_FEATURE = "feature";
-
-    private static void apply(final Object factory, final String kind, final 
String name, final ThrowingAction action) {
-        try {
-            action.run();
-        } catch (final Exception e) {
-            throw HardeningException.settingFailed(kind, name, factory, e);
-        }
-    }
-
-    static void setFeature(final DocumentBuilderFactory factory, final String 
feature, final boolean value) {
-        apply(factory, KIND_FEATURE, feature, () -> 
factory.setFeature(feature, value));
-    }
-
-    static void setFeature(final SAXParserFactory factory, final String 
feature, final boolean value) {
-        apply(factory, KIND_FEATURE, feature, () -> 
factory.setFeature(feature, value));
-    }
-
-    static void setFeature(final TransformerFactory factory, final String 
feature, final boolean value) {
-        apply(factory, KIND_FEATURE, feature, () -> 
factory.setFeature(feature, value));
-    }
-
-    static void setFeature(final XPathFactory factory, final String feature, 
final boolean value) {
-        apply(factory, KIND_FEATURE, feature, () -> 
factory.setFeature(feature, value));
-    }
-
-    static void setFeature(final SchemaFactory factory, final String feature, 
final boolean value) {
-        apply(factory, KIND_FEATURE, feature, () -> 
factory.setFeature(feature, value));
-    }
-
-    static void setFeature(final Validator validator, final String feature, 
final boolean value) {
-        apply(validator, KIND_FEATURE, feature, () -> 
validator.setFeature(feature, value));
-    }
-
-    static void setFeature(final ValidatorHandler handler, final String 
feature, final boolean value) {
-        apply(handler, KIND_FEATURE, feature, () -> 
handler.setFeature(feature, value));
-    }
-
-    static void setFeature(final XMLReader reader, final String feature, final 
boolean value) {
-        apply(reader, KIND_FEATURE, feature, () -> reader.setFeature(feature, 
value));
-    }
-
-    static void setOptionalFeature(final DocumentBuilderFactory factory, final 
String feature, final boolean value) {
-        try {
-            factory.setFeature(feature, value);
-        } catch (final Exception e) {
-            // Ignored: the implementation does not recognize this feature.
-        }
-    }
-
-    static void setOptionalFeature(final XMLReader reader, final String 
feature, final boolean value) {
-        try {
-            reader.setFeature(feature, value);
-        } catch (final Exception e) {
-            // Ignored: the implementation does not recognize this feature.
-        }
-    }
-
-    static void setOptionalFeature(final XPathFactory factory, final String 
feature, final boolean value) {
-        try {
-            factory.setFeature(feature, value);
-        } catch (final Exception e) {
-            // Ignored: the implementation does not recognize this feature.
-        }
-    }
-
-    static void setOptionalProperty(final XMLInputFactory factory, final 
String property, final Object value) {
-        trySetProperty(factory, property, value);
-    }
-
-    /**
-     * Sets a property on an {@link XMLReader} and returns whether the 
implementation accepted it.
-     *
-     * @param reader   The target reader on which to set the property.
-     * @param property The name of the property to set.
-     * @param value    The value of the property to set.
-     * @return {@code true} if the property was applied, {@code false} if the 
implementation rejected it.
-     */
-    static boolean trySetProperty(final XMLReader reader, final String 
property, final Object value) {
-        try {
-            reader.setProperty(property, value);
-            return true;
-        } catch (final Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * Sets a property on an {@link XMLInputFactory} and returns whether the 
implementation accepted it.
-     *
-     * @param factory   The target factory on which to set the property.
-     * @param property The name of the property to set.
-     * @param value     The value of the property to set.
-     * @return {@code true} if the property was applied, {@code false} if the 
implementation rejected it.
-     */
-    static boolean trySetProperty(final XMLInputFactory factory, final String 
property, final Object value) {
-        try {
-            factory.setProperty(property, value);
-            return true;
-        } catch (final Exception e) {
-            return false;
-        }
-    }
-
-    private JaxpSetters() {
-    }
-}
diff --git a/src/main/java/org/apache/commons/xml/SAXParserHardener.java 
b/src/main/java/org/apache/commons/xml/SAXParserHardener.java
index 5a9862a..5e0d67c 100644
--- a/src/main/java/org/apache/commons/xml/SAXParserHardener.java
+++ b/src/main/java/org/apache/commons/xml/SAXParserHardener.java
@@ -17,10 +17,6 @@
 
 package org.apache.commons.xml;
 
-import static org.apache.commons.xml.JaxpSetters.setFeature;
-import static org.apache.commons.xml.JaxpSetters.setOptionalFeature;
-import static org.apache.commons.xml.JaxpSetters.trySetProperty;
-
 import java.io.IOException;
 import java.util.Objects;
 
@@ -180,6 +176,39 @@ static XMLReader hardenReader(final XMLReader reader) {
         return new HardeningXMLReader(reader);
     }
 
+    private static void setFeature(final SAXParserFactory factory, final 
String feature, final boolean value) {
+        try {
+            factory.setFeature(feature, value);
+        } catch (final Exception e) {
+            throw HardeningException.settingFailed("feature", feature, 
factory, e);
+        }
+    }
+
+    private static void setFeature(final XMLReader reader, final String 
feature, final boolean value) {
+        try {
+            reader.setFeature(feature, value);
+        } catch (final Exception e) {
+            throw HardeningException.settingFailed("feature", feature, reader, 
e);
+        }
+    }
+
+    private static void setOptionalFeature(final XMLReader reader, final 
String feature, final boolean value) {
+        try {
+            reader.setFeature(feature, value);
+        } catch (final Exception e) {
+            // Ignored: the implementation does not recognize this feature.
+        }
+    }
+
+    private static boolean trySetProperty(final XMLReader reader, final String 
property, final Object value) {
+        try {
+            reader.setProperty(property, value);
+            return true;
+        } catch (final Exception e) {
+            return false;
+        }
+    }
+
     private SAXParserHardener() {
     }
 }
diff --git a/src/main/java/org/apache/commons/xml/StaxHardener.java 
b/src/main/java/org/apache/commons/xml/StaxHardener.java
index 6247fdd..128b44a 100644
--- a/src/main/java/org/apache/commons/xml/StaxHardener.java
+++ b/src/main/java/org/apache/commons/xml/StaxHardener.java
@@ -17,9 +17,6 @@
 
 package org.apache.commons.xml;
 
-import static org.apache.commons.xml.JaxpSetters.setOptionalProperty;
-import static org.apache.commons.xml.JaxpSetters.trySetProperty;
-
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
 
@@ -81,7 +78,7 @@ protected Object onUnresolved(final String publicID, final 
String systemID, fina
 
     static XMLInputFactory harden(final XMLInputFactory factory) {
         // Optional: Zephyr's StAX equivalent of 
XERCES_LOAD_EXTERNAL_DTD=false skips the external DTD subset entirely.
-        setOptionalProperty(factory, ZEPHYR_IGNORE_EXTERNAL_DTD, true);
+        trySetProperty(factory, ZEPHYR_IGNORE_EXTERNAL_DTD, true);
 
         // Each hook carries its own FallbackDenyXMLResolver floor; a caller 
can opt specific entities in through it, but cannot remove it (see
         // HardeningXMLInputFactory, which routes a caller-set resolver into 
the floor rather than replacing it). The DTD-subset and undeclared-entity hooks 
skip
@@ -95,6 +92,15 @@ && trySetProperty(factory, WSTX_UNDECLARED_ENTITY_RESOLVER, 
new Resolvers.Fallba
         return new HardeningXMLInputFactory(factory);
     }
 
+    private static boolean trySetProperty(final XMLInputFactory factory, final 
String property, final Object value) {
+        try {
+            factory.setProperty(property, value);
+            return true;
+        } catch (final Exception e) {
+            return false;
+        }
+    }
+
     private StaxHardener() {
     }
 }
diff --git a/src/main/java/org/apache/commons/xml/TransformerHardener.java 
b/src/main/java/org/apache/commons/xml/TransformerHardener.java
index f289363..b0d1b30 100644
--- a/src/main/java/org/apache/commons/xml/TransformerHardener.java
+++ b/src/main/java/org/apache/commons/xml/TransformerHardener.java
@@ -17,8 +17,6 @@
 
 package org.apache.commons.xml;
 
-import static org.apache.commons.xml.JaxpSetters.setFeature;
-
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
@@ -75,6 +73,14 @@ static TransformerFactory harden(final TransformerFactory 
factory) {
         return new HardeningTransformerFactory((SAXTransformerFactory) 
factory);
     }
 
+    private static void setFeature(final TransformerFactory factory, final 
String feature, final boolean value) {
+        try {
+            factory.setFeature(feature, value);
+        } catch (final Exception e) {
+            throw HardeningException.settingFailed("feature", feature, 
factory, e);
+        }
+    }
+
     private TransformerHardener() {
     }
 }
diff --git a/src/main/java/org/apache/commons/xml/XPathHardener.java 
b/src/main/java/org/apache/commons/xml/XPathHardener.java
index 38f3e9d..4a995cd 100644
--- a/src/main/java/org/apache/commons/xml/XPathHardener.java
+++ b/src/main/java/org/apache/commons/xml/XPathHardener.java
@@ -17,9 +17,6 @@
 
 package org.apache.commons.xml;
 
-import static org.apache.commons.xml.JaxpSetters.setFeature;
-import static org.apache.commons.xml.JaxpSetters.setOptionalFeature;
-
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
@@ -73,6 +70,22 @@ static XPathFactory harden(final XPathFactory factory) {
         return factory;
     }
 
+    private static void setFeature(final XPathFactory factory, final String 
feature, final boolean value) {
+        try {
+            factory.setFeature(feature, value);
+        } catch (final Exception e) {
+            throw HardeningException.settingFailed("feature", feature, 
factory, e);
+        }
+    }
+
+    private static void setOptionalFeature(final XPathFactory factory, final 
String feature, final boolean value) {
+        try {
+            factory.setFeature(feature, value);
+        } catch (final Exception e) {
+            // Ignored: the implementation does not recognize this feature.
+        }
+    }
+
     private XPathHardener() {
     }
 }
diff --git a/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java 
b/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java
index 08348ec..237d93e 100644
--- a/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java
+++ b/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java
@@ -40,7 +40,7 @@
  *
  * <p>Using {@code jdependency}, the same library {@code maven-shade-plugin}'s 
{@code minimizeJar} uses, this test computes each entry point's transitive class
  * closure over the compiled {@code target/classes} and pins it to an expected 
set. It keeps the DOM, SAX and StAX hardeners from silently regaining a 
dependency
- * on classes they should not need (for example the shared {@code JaxpSetters} 
or the sibling resolver floors), and records that the TrAX, XPath and schema 
entry
+ * on classes they should not need (for example the sibling resolver floors, 
or another hardener), and records that the TrAX, XPath and schema entry
  * points still pull the whole library through the {@link XmlFactories} 
re-hardening cycle. Update the expected sets deliberately: a change here is a 
change to what
  * a downstream shade includes.</p>
  */
@@ -53,25 +53,22 @@ class ShadingFootprintTest {
 
     private static final Set<String> DOCUMENT_BUILDER_HARDENER = set(
             "DocumentBuilderHardener", "HardeningDocumentBuilder", 
"HardeningDocumentBuilderFactory", CORE,
-            "JaxpSetters", "JaxpSetters$ThrowingAction",
             "Resolvers", "Resolvers$FallbackDenyResolver", 
"Resolvers$FallbackDenyLSResourceResolver", "Resolvers$FallbackDenyURIResolver",
             "Resolvers$FallbackDenyXMLResolver", 
"Resolvers$FallbackIgnoreXMLResolver");
 
     private static final Set<String> SAX_PARSER_HARDENER = set(
             "SAXParserHardener", "SAXParserHardener$DtdAwareDenyResolver", 
"SAXParserHardener$HardeningExpatXMLReader",
             "HardeningSAXParser", "HardeningSAXParserFactory", 
"HardeningXMLReader", CORE,
-            "JaxpSetters", "JaxpSetters$ThrowingAction",
             "Resolvers", "Resolvers$FallbackDenyResolver", 
"Resolvers$FallbackDenyLSResourceResolver", "Resolvers$FallbackDenyURIResolver",
             "Resolvers$FallbackDenyXMLResolver", 
"Resolvers$FallbackIgnoreXMLResolver");
 
     private static final Set<String> STAX_HARDENER = set(
             "StaxHardener", "StaxHardener$DtdSubsetFloor", 
"HardeningXMLInputFactory", CORE,
-            "JaxpSetters", "JaxpSetters$ThrowingAction",
             "Resolvers", "Resolvers$FallbackDenyResolver", 
"Resolvers$FallbackDenyLSResourceResolver", "Resolvers$FallbackDenyURIResolver",
             "Resolvers$FallbackDenyXMLResolver", 
"Resolvers$FallbackIgnoreXMLResolver");
 
     /** The TrAX/XPath/schema entry points all pull the whole library through 
{@link XmlFactories}; this is its class count (Phase 4 territory to reduce). */
-    private static final int WHOLE_LIBRARY_SIZE = 35;
+    private static final int WHOLE_LIBRARY_SIZE = 33;
 
     /** Entry points reported by the {@link #reportFootprint()} diagnostic, 
most-focused first, ending with the whole library. */
     private static final String[] REPORTED = {

Reply via email to