从Java 1.8迁移至OpenJDK 11时sun.security.x509等问题求助
解决Java 8迁移到OpenJDK 11时的sun.security.x509和BASE64Encoder依赖错误
嘿,这俩问题我太熟了——从Java 8迁到OpenJDK 11时,很多人都会踩这个坑!本质都是Java 9开始的模块系统把sun开头的内部API给藏起来了,不能再直接用啦。下面给你一步步解决:
1. 搞定sun.security.x509不可见的问题
- 为啥会报错? Java 9引入模块系统后,
sun.security.x509这类内部私有API被彻底移出了公共访问范围,JDK不再允许直接引用这些非标准类,强行用就会报“不可见”的错误。 - 该换啥用? 果断转向JDK标准库的
java.security.cert包,这是官方推荐的合规API,功能完全覆盖之前的需求:- 如果之前是手动构造X509证书对象(比如
X509CertImpl),现在用CertificateFactory生成标准的X509Certificate实例:// 替代旧的sun.security.x509.X509CertImpl初始化方式 CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new FileInputStream("your-cert.pem")); - 如果需要操作证书的专有名称(DN),用
X500Principal替代旧的sun.security.x509.X500Name:// 获取证书主体的DN信息 X500Principal subjectPrincipal = cert.getSubjectX500Principal(); String dn = subjectPrincipal.getName();
- 如果之前是手动构造X509证书对象(比如
- 重要提醒:别想着用
--add-exports=jdk.crypto.x509/sun.security.x509=ALL-UNNAMED这类参数强行开启访问,这只是临时的权宜之计,后续JDK版本可能会彻底删掉这些内部类,迁移到标准API才是长久方案。
2. 解决BASE64Encoder的错误
- 问题根源:
sun.misc.BASE64Encoder和BASE64Decoder都是JDK内部的非标准实现,Java 8就被标记为过时,到了Java 11直接被移除了支持,自然会报错。 - 完美替代:用JDK 8之后就自带的
java.util.Base64类,这是标准API,稳定又可靠:- Base64编码操作:
// 替代 new sun.misc.BASE64Encoder().encode(yourByteArray) String encodedStr = Base64.getEncoder().encodeToString(yourByteArray); - Base64解码操作:
// 替代 new sun.misc.BASE64Decoder().decodeBuffer(yourEncodedStr) byte[] decodedBytes = Base64.getDecoder().decode(yourEncodedStr);
- Base64编码操作:
- 额外小技巧:如果需要URL安全的Base64编码(比如在URL或Cookie里用),直接用
Base64.getUrlEncoder()和Base64.getUrlDecoder()就行。
最后检查Ant构建配置
因为我们用的都是JDK自带的标准API,所以不需要额外加依赖包,只要确保Ant的编译任务指定了OpenJDK 11版本就行。修改你的Ant脚本里的javac任务:
<javac srcdir="src/main/java" destdir="build/classes" source="11" target="11" encoding="UTF-8"/>
把原来的source="1.8"和target="1.8"替换成11,确保编译时用的是OpenJDK 11的语法和类库。
内容的提问来源于stack exchange,提问作者Gnik




