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
- Inspect the wrapped cause in the RuntimeException.
- Check the classpath for conflicting XML parsers (mvn dependency:tree | grep -i xml).
- Verify the JAXP factory resolves (System property javax.xml.parsers.SAXParserFactory overrides).
- 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
- Run mvn dependency:tree and remove duplicate XML parser implementations.
- Don't override javax.xml.parsers.SAXParserFactory unless necessary.
- Validate parser creation in a startup smoke test.
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
- No principal was found in the response from the CAS server.
- ${e.getMessage()}
- 类 {ruleClass} 未实现 IFillRuleHandler 接口
- {className} not found!
- 数据源URL配置格式不正确!
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/e09f700c450febb2.
Report an issue: GitHub.