jeecgboot/JeecgBoot · error · RuntimeException

Unable to create XMLReader

Error message

Unable to create XMLReader

What it means

XmlUtils.getXmlReader() builds a hardened SAXParserFactory (disallow-doctype-decl, external general/parameter entities off, load-external-dtd off) and obtains an XMLReader. Any failure creating the parser/reader is wrapped as RuntimeException 'Unable to create XMLReader'.

Source

Thrown at jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/cas/util/XmlUtils.java:85

     * Get an instance of an XML reader from the XMLReaderFactory.
     *
     * @return the XMLReader.
     */
    public static XMLReader getXmlReader() {
        try {
            //update-begin---author:wangshuai---date:2026-03-30---for:【issues/9422】XmlUtils.extractCustomAttributes可能存在疑似的外部实体依赖漏洞---
            final SAXParserFactory spf = SAXParserFactory.newInstance();
            spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
            spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
            spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            final XMLReader reader = spf.newSAXParser().getXMLReader();
            //update-end---author:wangshuai---date:2026-03-30---for:【issues/9422】XmlUtils.extractCustomAttributes可能存在疑似的外部实体依赖漏洞---
            reader.setFeature("http://xml.org/sax/features/namespaces", true);
            reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
            return reader;
        } catch (final Exception e) {
            throw new RuntimeException("Unable to create XMLReader", e);
        }
    }


    /**
     * Retrieve the text for a group of elements. Each text element is an entry
     * in a list.
     * <p>This method is currently optimized for the use case of two elements in a list.
     *
     * @param xmlAsString the xml response
     * @param element     the element to look for
     * @return the list of text from the elements.
     */
    public static List<String> getTextForElements(final String xmlAsString, final String element) {
        final List<String> elements = new ArrayList<String>(2);
        final XMLReader reader = getXmlReader();

        final DefaultHandler handler = new DefaultHandler() {

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Inspect the wrapped cause in the RuntimeException.
  2. Check the classpath for conflicting XML parsers (mvn dependency:tree | grep -i xml).
  3. Verify the JAXP factory resolves (System property javax.xml.parsers.SAXParserFactory overrides).
  4. Test on a clean classpath to isolate a dependency conflict.
Defensive patterns

Strategy: try-catch

Validate before calling

// validate the JAXP factory is resolvable at startup
SAXParserFactory f = SAXParserFactory.newInstance();
f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
XMLReader r = f.newSAXParser().getXMLReader();

Try / catch

try {
    return spf.newSAXParser().getXMLReader();
} catch (Exception e) {
    log.error("无法创建 XMLReader,检查 classpath XML 解析器冲突", e);
    throw new RuntimeException("Unable to create XMLReader", e);
}

Prevention

When it happens

Trigger: JAXP misconfiguration; a conflicting/stale XML parser (xerces/saxon/aalto) on the classpath; the JRE blocks the feature; security manager restrictions; shaded jar breaking ServiceLoader.

Common situations: Dependency brings an incompatible stax/sax impl; restricted server JRE; classpath shading reordered SPI providers.

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/e09f700c450febb2. Report an issue: GitHub.