Tomcat9+Java11下HttpsURLConnectionOldImpl报错排查与修复
修复配置调整
按优先级选以下方案即可解决问题:
- 直接删除手动配置的
java.protocol.handler.pkgs=org.apache.catalina.webresources全局参数。Tomcat 9本身会自动处理内部Web资源加载相关的协议注册,不需要用户手动设置该系统属性,绝大多数场景下手动配置这个参数都是多余操作。 - 如果有特殊需求必须保留该配置,禁止直接覆盖属性原值,要将原有属性值追加到配置后,最终值设为
org.apache.catalina.webresources|${java.protocol.handler.pkgs},保证JDK原生协议处理包的查找逻辑不被破坏。 - 临时应急可以在代码层绕开全局协议加载逻辑,初始化URL时显式传入JDK默认的HTTPS协议处理器:
该方案侵入性较强,仅推荐临时排障使用,长期还是要修正系统属性配置。HttpsURLConnection con = (HttpsURLConnection) new URL( null, protocol + hostname + path, new sun.net.www.protocol.https.Handler() ).openConnection(); - 全量排查Tomcat启动脚本、应用配置文件、容器级公共配置里是否有其他位置篡改
java.protocol.handler.pkgs属性,确保没有其他配置覆盖该属性的默认值。
HttpsURLConnectionOldImpl被加载的根本原因
JDK对URL协议处理器的查找有固定优先级逻辑:
- 优先查找通过
URL.setURLStreamHandlerFactory()注册的全局自定义处理器工厂 - 无自定义工厂时,按
java.protocol.handler.pkgs系统属性中配置的包顺序,逐个匹配[包路径].[协议名].Handler类,找到即使用 - 上述路径均无匹配实现时,才会回退到JDK内置默认路径
sun.net.www.protocol下的处理器,该路径下的HTTPS处理器返回的连接才是标准javax.net.ssl.HttpsURLConnection实现。
你当前直接把java.protocol.handler.pkgs赋值为org.apache.catalina.webresources,相当于清空了该属性的原有默认值。JDK查找HTTPS协议处理器时,会优先到org.apache.catalina.webresources.https路径下匹配,而该路径下恰好存在Tomcat为兼容极旧版本JDK(Java 1.4及更早)保留的遗留Handler类,这个Handler返回的连接实现就是com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl。
这个类是Java标准化HTTPS连接接口前的遗留实现,和Java 5之后正式提供的javax.net.ssl.HttpsURLConnection分属完全独立的类继承体系,没有继承关系,因此强转时会直接抛出类转换异常。
本质上Tomcat在org.apache.catalina.webresources包下提供的协议处理器仅用于处理war:、jar:这类容器内部的自定义资源协议,本身不具备处理HTTPS公网协议的能力,错误的全局属性配置让JDK误加载了这个遗留兼容类,才触发了报错。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

