Java 8迁移至OpenJDK 11:com.sun.org.apache.xml.internal类无法访问求助
你遇到的问题根源很明确:这些com.sun.org.apache.xml.internal.*和com.sun.org.apache.xpath.internal.*包都是JDK的私有内部API,从Java 9引入模块化系统开始,JDK就严格限制了对这类内部API的访问,到Java 11时这种限制进一步强化,直接引用就会出现“无法访问”的编译错误。
而且这些API本身就不是Java标准库的一部分,Oracle和OpenJDK团队一直明确不建议依赖它们——它们随时可能被修改、移除,完全没有兼容性保证。你尝试的--add-exports方案没生效,大概率是因为参数配置的模块路径不对,不过更根本的解决思路是替换这些内部依赖为公开的标准/第三方库,而不是强行绕过模块化限制。
推荐方案:替换为公开的Apache XML库
这些JDK内部类其实是内嵌的Apache Xalan项目的代码,Xalan本身是公开维护的开源库,完全可以直接引入项目中替换内部API:
替换依赖包
在你的项目构建文件(Maven/Gradle)中添加Apache Xalan的依赖:- Maven示例:
<dependency> <groupId>xalan</groupId> <artifactId>xalan</artifactId> <version>2.7.2</version> <!-- 可使用最新稳定版 --> </dependency> - Gradle示例:
implementation 'xalan:xalan:2.7.2'
- Maven示例:
修改代码中的import语句
将原来的内部API导入替换为Xalan公开包的对应类:- 原
import com.sun.org.apache.xml.internal.dtm.DTM;→import org.apache.xml.dtm.DTM; - 原
import com.sun.org.apache.xml.internal.dtm.DTMManager;→import org.apache.xml.dtm.DTMManager; - 原
import com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2DTM;→import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM; - 原
import com.sun.org.apache.xml.internal.utils.XMLStringFactory;→import org.apache.xml.utils.XMLStringFactory; - 原
import com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl;→import org.apache.xpath.objects.XMLStringFactoryImpl;
- 原
替换完成后,项目就不再依赖JDK内部API,兼容性和稳定性都会大幅提升,也不会再出现编译错误。
临时 workaround:通过Eclipse配置绕过模块化限制(不推荐)
如果因为某些原因暂时无法替换代码,可以尝试正确配置--add-exports参数让Eclipse编译通过,但这只是权宜之计:
- 打开项目属性 → Java Build Path → Libraries
- 展开JRE System Library,选择Modulepath下的JDK条目,点击Edit
- 在弹出的对话框中,找到VM arguments输入框,添加以下参数:
--add-exports jdk.xml.xpath/com.sun.org.apache.xml.internal.dtm=ALL-UNNAMED --add-exports jdk.xml.xpath/com.sun.org.apache.xml.internal.dtm.ref.sax2dtm=ALL-UNNAMED --add-exports jdk.xml.xpath/com.sun.org.apache.xml.internal.utils=ALL-UNNAMED --add-exports jdk.xml.xpath/com.sun.org.apache.xpath.internal.objects=ALL-UNNAMED - 点击确认后,重新编译项目。如果是运行时也需要这些参数,还要在Run Configurations的VM arguments中添加同样的内容。
再次强调:这种方法只是临时绕过限制,随着JDK版本迭代,这些内部API可能会被彻底移除,到时候项目会直接崩溃,所以优先推荐替换为公开库的方案。
对你疑问的明确回答
是的,这些包已经变成了受限制的内部包,Java 9之后就被模块化系统封装起来,不再允许开发者直接访问。从长期维护的角度看,必须替换为标准API或者公开的第三方库,才能保证项目在后续JDK版本中的兼容性。
内容的提问来源于stack exchange,提问作者Rasha Elsayed




