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
相关产品推荐
相关产品推荐

