OpenJDK 1.8.0_252环境下Netty配置ALPN无需Jetty ALPN Agent的方法
解决OpenJDK 1.8.0_252下Netty使用原生ALPN无需Jetty Agent的配置方案
我来帮你搞定这个问题——你碰到的java.lang.NoClassDefFoundError: org/eclipse/jetty/alpn/ALPN$Provider异常,本质是Netty默认逻辑还在优先尝试加载Jetty的ALPN实现,而没有自动切换到OpenJDK 1.8.0_252自带的标准ALPN API。按照下面的步骤配置,就能让Netty用上JDK原生的ALPN支持,不再依赖jetty-alpn-agent:
1. 确保使用兼容的Netty版本
首先,你需要使用Netty 4.1.50.Final及以上版本——这个版本开始,Netty正式支持OpenJDK 8u252+的原生ALPN实现。如果你的Netty版本低于这个,先升级到符合要求的版本。
2. 清理不必要的依赖
- 不要主动引入任何
jetty-alpn相关的依赖包; - 如果你的项目通过其他依赖间接引入了
jetty-alpn-api或jetty-alpn-openjdk8-client/server,需要在构建工具中排除这些传递依赖:- Maven示例:
<dependency> <groupId>io.netty</groupId> <artifactId>netty-handler</artifactId> <version>你的Netty版本</version> <exclusions> <exclusion> <groupId>org.eclipse.jetty.alpn</groupId> <artifactId>jetty-alpn-api</artifactId> </exclusion> </exclusions> </dependency> - Gradle示例:
implementation('io.netty:netty-handler:你的Netty版本') { exclude group: 'org.eclipse.jetty.alpn', module: 'jetty-alpn-api' }
- Maven示例:
3. 配置Netty使用JDK原生ALPN
在创建Netty的SslContext时,明确指定使用JDK自带的ALPN协商器,而不是Jetty的实现:
服务器端配置示例
// 创建SSL上下文 SslContext sslContext = SslContextBuilder.forServer(new File("server.crt"), new File("server.key")) // 配置ALPN,使用JDK原生提供者 .applicationProtocolConfig(new ApplicationProtocolConfig( ApplicationProtocolConfig.Protocol.ALPN, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, "http/1.1", "h2" // 你需要支持的协议列表 )) .build(); // 在ChannelPipeline中添加SslHandler pipeline.addLast(sslContext.newEngine(channel.alloc()));
或者直接指定JDK ALPN协商器
如果你需要更精细的控制,可以直接使用JdkAlpnApplicationProtocolNegotiator并指定默认提供者:
JdkAlpnApplicationProtocolNegotiator alpnNegotiator = new JdkAlpnApplicationProtocolNegotiator( ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, "h2", "http/1.1" ); SslContext sslContext = SslContextBuilder.forServer(...) .applicationProtocolConfig(alpnNegotiator.applicationProtocolConfig()) .build();
4. 验证JDK原生ALPN是否启用
可以通过以下方式确认你的JDK环境已经开启ALPN:
- 检查系统属性
jdk.tls.alpn.enabled是否为true(OpenJDK 1.8.0_252默认是开启的); - 代码中验证:
SSLEngine engine = SSLContext.getDefault().createSSLEngine(); if (engine instanceof ExtendedSSLEngine) { System.out.println("JDK原生ALPN已支持"); } else { System.out.println("JDK不支持原生ALPN,请检查版本"); }
完成这些配置后,Netty就会使用OpenJDK自带的ALPN实现,不再依赖Jetty的ALPN扩展,也就不会再抛出那个NoClassDefFoundError了。
内容的提问来源于stack exchange,提问作者user2610356
相关产品推荐
相关产品推荐

