升级Spring Boot 3后Tomcat 10.x中AbstractHttp11Protocol方法缺失编译报错求助
问题背景
升级Spring Boot 3后,Tomcat 10.x移除了AbstractHttp11Protocol类中用于配置SSL/TLS的一系列setter方法(如setKeystoreType、setKeystoreFile等),导致原mTLS配置代码出现编译错误。
原配置代码
@Bean public WebServerFactoryCustomizer<TomcatServletWebServerFactory> containerCustomizer() { return configurableEmbeddedServletContainer -> { if (configurableEmbeddedServletContainer != null) { TomcatServletWebServerFactory tomcatEmbeddedServletContainerFactory = configurableEmbeddedServletContainer; tomcatEmbeddedServletContainerFactory.addAdditionalTomcatConnectors(additionalConnector(serverConfig())); } }; } private Connector additionalConnector(ServerConfig serverConfig) { SslConfig sslConfig = serverConfig.getSsl(); Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); connector.setScheme(SCHEME); connector.setSecure(true); connector.setPort(serverConfig.getPort()); protocol.setSSLEnabled(true); // 以下代码出现编译错误 protocol.setKeystoreType(sslConfig.getKeyStoreType()); protocol.setKeystoreFile(sslConfig.getKeyStore()); protocol.setKeystorePass(String.valueOf(sslConfig.getKeyStorePassword())); protocol.setKeyPass(String.valueOf(sslConfig.getKeyPassword())); protocol.setTruststoreType(sslConfig.getTrustStoreType()); protocol.setTruststoreFile(sslConfig.getTrustStore()); protocol.setTruststorePass(String.valueOf(sslConfig.getTrustStorePW())); protocol.setSSLProtocol(TLSV_1_2); protocol.setClientAuth("true"); return connector; }
编译错误信息
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.11.0:compile (default-compile) on project xxx module: Compilation failure: Compilation failure:
[ERROR] /controller/HttpsRequestFactory.java:[71,30] com.xxx.HttpsRequestFactory.SelectByAlias is not abstract and does not override abstract method chooseAlias(java.util.Map<java.lang.String,org.apache.hc.core5.ssl.PrivateKeyDetails>,javax.net.ssl.SSLParameters) in org.apache.hc.core5.ssl.PrivateKeyStrategy
[ERROR] /controller/HttpsRequestFactory.java:[81,17] method does not override or implement a method from a supertype
[ERROR] /authentication/TomcatConnectorAutoConfiguration.java:[57,25] cannot find symbol
[ERROR] symbol: method setKeystoreType(java.lang.String)
[ERROR] location: variable protocol of type org.apache.coyote.http11.Http11NioProtocol
[ERROR] /authentication/TomcatConnectorAutoConfiguration.java:[58,25] cannot find symbol
[ERROR] symbol: method setKeystoreFile(java.lang.String)
[ERROR] location: variable protocol of type org.apache.coyote.http11.Http11NioProtocol
[ERROR] /authentication/TomcatConnectorAutoConfiguration.java:[59,25] cannot find symbol
[ERROR] symbol: method setKeystorePass(java.lang.String)
[ERROR] location: variable protocol of type org.apache.coyote.http11.Http11NioProtocol
[ERROR] /authentication/TomcatConnectorAutoConfiguration.java:[60,25] cannot find symbol
[ERROR] symbol: method setKeyPass(java.lang.String)
[ERROR] location: variable protocol of type org.apache.coyote.http11.Http11NioProtocol
[ERROR] /authentication/TomcatConnectorAutoConfiguration.java:[61,25] cannot find symbol
[ERROR] symbol: method setTruststoreType(java.lang.String)
[ERROR] location: variable protocol of type org.apache.coyote.http11.Http11NioProtocol
[ERROR] /authentication/TomcatConnectorAutoConfiguration.java:[62,25] cannot find symbol
[ERROR] symbol: method setTruststoreFile(java.lang.String)
[ERROR] location: variable protocol of type org.apache.coyote.http11.Http11NioProtocol
[ERROR] /authentication/TomcatConnectorAutoConfiguration.java:[63,25] cannot find symbol
[ERROR] symbol: method setTruststorePass(java.lang.String)
[ERROR] location: variable protocol of type org.apache.coyote.http11.Http11NioProtocol
[ERROR] /authentication/TomcatConnectorAutoConfiguration.java:[64,25] cannot find symbol
[ERROR] symbol: method setSSLProtocol(java.lang.String)
[ERROR] location: variable protocol of type org.apache.coyote.http11.Http11NioProtocol
[ERROR] /authentication/TomcatConnectorAutoConfiguration.java:[65,25] cannot find symbol
[ERROR] symbol: method setClientAuth(java.lang.String)
[ERROR] location: variable protocol of type org.apache.coyote.http11.Http11NioProtocol
解决方案
1. Tomcat mTLS配置修改
Tomcat 10.x改用SslHostConfig和SslHostConfigCertificate来管理SSL/TLS配置,替代原有的直接在Http11NioProtocol上调用setter的方式。修改后的additionalConnector方法如下:
private Connector additionalConnector(ServerConfig serverConfig) { SslConfig sslConfig = serverConfig.getSsl(); Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); connector.setScheme(SCHEME); connector.setSecure(true); connector.setPort(serverConfig.getPort()); protocol.setSSLEnabled(true); // 创建SslHostConfig并配置客户端认证、协议 SslHostConfig sslHostConfig = new SslHostConfig(); sslHostConfig.setClientAuth("true"); // 强制客户端认证,对应原mTLS配置 sslHostConfig.setProtocols(TLSV_1_2); // 设置TLS协议版本 // 创建SslHostConfigCertificate并配置密钥库 SslHostConfigCertificate certificate = new SslHostConfigCertificate(sslHostConfig, SslHostConfigCertificate.Type.RSA); certificate.setKeystoreType(sslConfig.getKeyStoreType()); certificate.setKeystoreFile(sslConfig.getKeyStore()); certificate.setKeystorePass(String.valueOf(sslConfig.getKeyStorePassword())); certificate.setKeyPass(String.valueOf(sslConfig.getKeyPassword())); // 配置信任库 sslHostConfig.setTruststoreType(sslConfig.getTrustStoreType()); sslHostConfig.setTruststoreFile(sslConfig.getTrustStore()); sslHostConfig.setTruststorePass(String.valueOf(sslConfig.getTrustStorePW())); // 将证书添加到SslHostConfig,再将SslHostConfig添加到协议 sslHostConfig.addCertificate(certificate); protocol.addSslHostConfig(sslHostConfig); return connector; }
2. PrivateKeyStrategy实现类修改
Spring Boot 3依赖HttpClient 5,PrivateKeyStrategy的chooseAlias方法签名已变更,需修改SelectByAlias类实现新方法:
private static class SelectByAlias implements PrivateKeyStrategy { private final String alias; public SelectByAlias(String alias) { this.alias = alias; } @Override public String chooseAlias(Map<String, PrivateKeyDetails> aliases, SSLParameters sslParameters) { return alias; } }
说明
Tomcat 10.x移除旧SSL配置API是为了统一使用更灵活的SslHostConfig机制,支持多证书、多域名等场景,同时对齐现代TLS配置最佳实践。
内容的提问来源于stack exchange,提问作者Jagdish Raika

