ElementNSImpl在Eclipse与Java Zulu 11环境下无法使用问题求助
解决Java 11下
com.sun.org.apache.xerces.internal.dom.ElementNSImpl不可访问的问题 问题根源拆解
Java 9引入的模块系统(JPMS)把JDK内部API的访问权限收紧了不少。你碰到的com.sun.org.apache.xerces.internal.dom包属于java.xml模块,但这个模块并没有将该包导出给外部应用使用——哪怕你在Zulu 11的jar里看到这个类是"公共"的,模块系统的访问规则优先级更高,就是会阻止你访问。
在Java 8时期,内部API是可以直接访问的,所以你通过引入xerces:xercesImpl:2.6.2-jaxb-1.0.6还能绕开JDK内部的实现,但到了Java 11,这套逻辑直接失效了。
两个可行的解决方案
方案1:替换为标准API或公开的Xerces实现(首推)
既然你的代码仅在一处用到ElementNSImpl,最稳妥的做法是换成合规的实现:
- 如果你只是需要处理带命名空间的Element,优先用标准的
org.w3c.dom.Element接口即可,它本身就包含getNamespaceURI()、getLocalName()等命名空间相关方法,完全没必要依赖具体的实现类。 - 若确实需要使用Xerces的实现,直接引入官方维护的公开Xerces库,别再依赖JDK内部的版本:
在build.gradle中更新依赖:
然后把代码里的dependencies { implementation 'xerces:xercesImpl:2.12.2' // 用最新稳定版替换旧的2.6.2版本 }com.sun.org.apache.xerces.internal.dom.ElementNSImpl替换为org.apache.xerces.dom.ElementNSImpl——这是公开受支持的API,模块系统不会拦截。
方案2:临时放宽模块访问限制(仅应急使用)
如果暂时无法修改代码,也可以通过JVM参数让java.xml模块把内部包开放给你的应用,但这只是权宜之计,未来Java版本可能会彻底移除这些内部API:
- Gradle构建时添加编译参数:
在Eclipse中运行时,需要在运行配置的VM参数里添加:tasks.withType(JavaCompile) { options.compilerArgs += [ '--add-exports', 'java.xml/com.sun.org.apache.xerces.internal.dom=ALL-UNNAMED' ] }
注意:这种方式会让代码依赖非标准的内部API,后续升级Java版本大概率会出现兼容性问题,不建议长期使用。--add-exports java.xml/com.sun.org.apache.xerces.internal.dom=ALL-UNNAMED
总结
优先选择方案1,替换为标准API或公开的Xerces实现,这是符合Java模块化规范的长期解决方案;方案2仅作为临时过渡的应急手段。
内容的提问来源于stack exchange,提问作者Marco Sulla
相关产品推荐
相关产品推荐

