You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenJDK 8下JAXB+SAX解析XML遇Connection Reset异常求助

问题:OpenJDK 8下JAXB反序列化XML出现SSL连接重置异常

我先从网络下载XML报告并将原始XML存入String变量,随后创建SAXParser的代码如下:

try {
    SAXParserFactory spf = SAXParserFactory.newInstance();

    spf.setXIncludeAware(true);
    spf.setNamespaceAware(true);
    spf.setValidating(true); // Not required for JAXB/XInclude

    XMLReader xr = (XMLReader) spf.newSAXParser().getXMLReader();
    xr.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false); //with true report could not be parsed
    xr.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); // This may not be strictly required as DTDs shouldn't be allowed at all, per previous line.
    xr.setFeature("http://xml.org/sax/features/external-general-entities", false);
    xr.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
    return new SAXSource(xr,  new InputSource(new StringReader(output)));
} catch (Exception e) {
    e.printStackTrace();
}

接着调用JAXB反序列化方法:

jaxbUnmarshaller.unmarshal(saxSource);

触发了如下异常,经查ClassLoader为null。该代码在Oracle Java 8下可正常运行,但在OpenJDK version "1.8.0_392"中出现问题。

异常信息:

JAXP: find factoryId =javax.xml.parsers.SAXParserFactory
JAXP: loaded from fallback value: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
JAXP: created new instance of class com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl using ClassLoader: null
javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.net.ssl.SSLException: Connection reset]
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:246)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:140)
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:123)
        at com.matrix.clientmanager.ws.nipr.ScbDownloadReport.downloadReport(ScbDownloadReport.java:74)
        at com.matrix.clientmanager.autobatch.RunLicenseConfig.checkReportResults(RunLicenseConfig.java:325)
        at com.matrix.clientmanager.autobatch.RunLicenseConfig.<init>(RunLicenseConfig.java:87)
        at com.matrix.clientmanager.autobatch.AutoBatch.runLicenseConfig(AutoBatch.java:3352)
        at com.matrix.clientmanager.autobatch.RunAutoBatch.main(RunAutoBatch.java:1111)
Caused by: javax.net.ssl.SSLException: Connection reset
        at sun.security.ssl.Alert.createSSLException(Alert.java:127)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:331)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:274)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:269)
        at sun.security.ssl.SSLTransport.decode(SSLTransport.java:138)
        at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1401)
        at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1309)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1572)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1500)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:268)
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:648)
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1305)
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:1271)
        at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:264)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1160)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1044)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:958)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:601)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:504)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:642)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
        ... 8 more
        Suppressed: java.net.SocketException: Broken pipe (Write failed)
                at java.net.SocketOutputStream.socketWrite0(Native Method)
                at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
                at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
                at sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
                at sun.security.ssl.TransportContext.fatal(TransportContext.java:362)
                ... 35 more
Caused by: java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(SocketInputStream.java:210)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:464)
        at sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:165)
        at sun.security.ssl.SSLTransport.decode(SSLTransport.java:109)
        ... 32 more

问题根源

从异常栈可见,解析器尝试加载外部DTD时发起了HTTPS请求,导致连接重置。虽然配置了load-external-dtd为false,但开启setValidating(true)且disallow-doctype-decl设为false后,OpenJDK的Xerces实现仍会触发DTD解析逻辑,再加上ClassLoader为null影响了SSL上下文初始化,最终导致连接失败。

修复方案

  1. 关闭XML验证:注释已说明验证非JAXB/XInclude必需,直接关闭验证避免触发DTD解析:将spf.setValidating(true)改为false。
  2. 显式设置ClassLoader:创建SAXParserFactory时指定当前线程上下文类加载器,避免出现null ClassLoader:
    spf.setClassLoader(Thread.currentThread().getContextClassLoader());
    
  3. 强化外部资源禁用配置:额外添加禁用DTD语法加载的feature,彻底阻止外部资源请求。

修改后的完整代码

try {
    SAXParserFactory spf = SAXParserFactory.newInstance();
    spf.setClassLoader(Thread.currentThread().getContextClassLoader()); // 显式设置类加载器
    spf.setXIncludeAware(true);
    spf.setNamespaceAware(true);
    spf.setValidating(false); // 关闭验证,避免触发DTD解析

    XMLReader xr = spf.newSAXParser().getXMLReader();
    xr.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false);
    xr.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
    xr.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); // 额外禁用DTD语法加载
    xr.setFeature("http://xml.org/sax/features/external-general-entities", false);
    xr.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

    return new SAXSource(xr, new InputSource(new StringReader(output)));
} catch (Exception e) {
    e.printStackTrace();
}

补充说明

OpenJDK与Oracle JDK的Xerces实现存在细微差异,对验证和外部资源加载的处理逻辑不一致,这是兼容性问题的核心。若仍需XML结构校验,建议改用Schema验证(spf.setSchema(...)),避免依赖DTD带来的外部资源加载风险。

内容的提问来源于stack exchange,提问作者user2654788

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:25:07