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

JDK17升级后XMLSignatureFactory实例化报错:无法访问XMLDSigRI类

JDK17升级后XMLSignatureFactory实例化报错解决方案

我们通过XMLSignatureFactory按以下方式获取实例,代码在JDK12中运行正常,但升级到JDK17后出现运行时错误:

String providerName = System.getProperty("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
try {
    return XMLSignatureFactory.getInstance("DOM", (Provider) Class.forName(providerName).newInstance());
}

报错信息:

Caused by: java.lang.IllegalAccessException: class com.test.OutboundMessageHandlerImpl cannot access class org.jcp.xml.dsig.internal.dom.XMLDSigRI (in module java.xml.crypto) because module java.xml.crypto does not export org.jcp.xml.dsig.internal.dom to unnamed module @6580cfdd

问题原因

JDK9引入的模块系统(JPMS)对内部API的访问做了严格限制,org.jcp.xml.dsig.internal.dom.XMLDSigRI是java.xml.crypto模块的内部实现类,JDK17进一步收紧了权限,不允许未命名模块(你的代码所在模块)访问该内部包的类。

解决方案

  • 优先推荐:使用标准API获取实例
    直接调用XMLSignatureFactory.getInstance("DOM")即可,JDK会自动加载合适的Provider,代码符合规范且无需依赖内部API:

    return XMLSignatureFactory.getInstance("DOM");
    
  • 自定义Provider场景(不依赖JDK内部类)
    如果有特殊需求必须指定Provider,不要使用JDK内部的实现类,改用公开的第三方Provider(比如Apache Santuario)。或者将你的代码模块化,在module-info.java中声明依赖并申请访问权限:

    module com.test {
        requires java.xml.crypto;
        opens com.test to java.xml.crypto;
        requires transitive java.xml;
    }
    

    注意:依赖内部API存在后续JDK版本兼容性风险,不推荐长期使用。

  • 临时 workaround(不建议长期用)
    启动JVM时添加参数放宽模块访问限制:

    --add-exports java.xml.crypto/org.jcp.xml.dsig.internal.dom=ALL-UNNAMED
    

    该参数允许未命名模块访问指定内部包,但会破坏模块封装性,后续JDK版本可能取消支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:57:18