OpenJDK 17中XSLT转换抛NullPointerException,疑为Xalan bug?
问题原因与解决方案
核心问题是样式表源(StreamSource/DOMSource)未设置systemId,Xalan的XSLTC实现内部依赖这个属性做后续处理,缺失时会触发空指针异常,而非预期的友好错误提示。
具体修复方案
方案1:修复StreamSource的使用
不要只传入输入流,同时设置样式表的URL作为systemId:
Document doc = generateXml(catalog); URL stylesheet = getClass().getResource("catalog_html.xslt"); log.debug("stylesheet url: {}", stylesheet); // 创建StreamSource并设置systemId StreamSource styleSource = new StreamSource(stylesheet.openStream()); styleSource.setSystemId(stylesheet.toString()); Transformer transformer = TransformerFactory.newInstance() .newTransformer(styleSource); transformer.transform(new DOMSource(doc), new StreamResult(out));
或者更简洁的方式,直接用URL的URI字符串构造StreamSource:
StreamSource styleSource = new StreamSource(stylesheet.toURI().toString());
方案2:修复DOMSource的使用
解析样式表为DOM后,给DOMSource设置systemId:
Document doc = generateXml(catalog); URL stylesheet = getClass().getResource("catalog_html.xslt"); Document ss = DocumentBuilderFactory.newInstance() .newDocumentBuilder() .parse(stylesheet.openStream()); // 给DOMSource设置systemId DOMSource domSource = new DOMSource(ss); domSource.setSystemId(stylesheet.toString()); Transformer transformer = TransformerFactory.newInstance() .newTransformer(domSource); transformer.transform(new DOMSource(doc), new StreamResult(out));
原因解释
Xalan的XSLTC实现(即你异常栈中com.sun.org.apache.xalan.internal.xsltc.trax包下的代码)在处理样式表时,会尝试使用systemId做内部标识、资源路径解析等操作,即使你的样式表没有外部依赖,缺失该属性也会导致内部代码访问null值,触发非预期的NullPointerException,而非明确的错误提示。
内容的提问来源于stack exchange,提问作者queeg
相关产品推荐
相关产品推荐

