Spring Boot 3.2.0升级到3.3.0后Netty方法缺失异常问题
问题:Spring Boot 3.3.0升级后Netty方法不存在异常
异常信息
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.reactive.function.client.WebClient]: Factory method 'webClient' threw exception with message: 'io.netty.resolver.dns.DnsNameResolverBuilder io.netty.resolver.dns.DnsNameResolverBuilder.socketChannelFactory(io.netty.channel.ChannelFactory, boolean)' Caused by: java.lang.NoSuchMethodError: 'io.netty.resolver.dns.DnsNameResolverBuilder io.netty.resolver.dns.DnsNameResolverBuilder.socketChannelFactory(io.netty.channel.ChannelFactory, boolean)'
客户端配置
SslContext sslContext = SslContextBuilder.forClient() .sslProvider(SslProvider.OPENSSL) .keyManager(clientCertificateHandler.keyManagerFactory()) .trustManager(InsecureTrustManagerFactory.INSTANCE) .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE) .applicationProtocolConfig( new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2)) .build(); var provider = ConnectionProvider .builder("app-provider") .maxConnections(500) .pendingAcquireTimeout(Duration.ofSeconds(45)) .maxIdleTime(Duration.ofSeconds(600)).build(); HttpClient httpClient = HttpClient. create(provider) .secure(sslContextSpec -> { sslContextSpec.sslContext(sslContext) .handlerConfigurator(sslHandler -> { SSLEngine engine = sslHandler.engine(); SSLParameters params = new SSLParameters(); List<SNIMatcher> matchers = new LinkedList<>(); SNIMatcher matcher = new SNIMatcher(0) { @Override public boolean matches(SNIServerName serverName) { return true; } }; matchers.add(matcher); params.setSNIMatchers(matchers); engine.setSSLParameters(params); }); }) .runOn(reactorResourceFactory.getLoopResources()) .compress(true) .keepAlive(true) .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000) .option(EpollChannelOption.TCP_KEEPIDLE, 300) .option(EpollChannelOption.TCP_KEEPINTVL, 60) .responseTimeout(Duration.ofSeconds(120)) .protocol(HttpProtocol.H2) .baseUrl(ssoServiceUrl) .doOnConnected(conn -> conn .addHandlerLast(new ReadTimeoutHandler(120, TimeUnit.SECONDS)) .addHandlerLast(new WriteTimeoutHandler(5, TimeUnit.SECONDS))) ; return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .baseUrl(ssoServiceUrl) .filter(modifyRequestHeaders(new LinkedMultiValueMap<>())) .filter((request, exchangeFunction) -> { return exchangeFunction .exchange(request).doOnNext(resp -> { var responseCookies = resp.cookies(); if (responseCookies.containsKey(ACCESS_KEY_COOKIE)) { tokenHolder.updateAccessToken(responseCookies.get(ACCESS_KEY_COOKIE).get(0).getValue()); } }); }) .build();
POM依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>io.netty</groupId> <artifactId>netty-common</artifactId> </exclusion> <exclusion> <groupId>io.netty</groupId> <artifactId>netty-handler</artifactId> </exclusion> <exclusion> <groupId>io.netty</groupId> <artifactId>netty-transport</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>${netty.version}</version> </dependency> <dependency> <groupId>kz.aitups.sso.auth</groupId> <artifactId>webflux</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- https://mvnrepository.com/artifact/io.netty/netty-transport-native-kqueue --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-transport-native-kqueue</artifactId> <version>${netty.version}</version> <classifier>osx-x86_64</classifier> </dependency> <!-- https://mvnrepository.com/artifact/io.netty/netty-tcnative-boringssl-static --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-tcnative-boringssl-static</artifactId> <version>${netty.tcnative.version}</version> <scope>runtime</scope> </dependency> <!-- https://mvnrepository.com/artifact/io.netty/netty-tcnative --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-tcnative</artifactId> <version>${netty.tcnative.version}</version> <scope>runtime</scope> </dependency> </dependencies>
解决方案
1. 移除手动指定的netty-all依赖
Spring Boot 3.3.0已通过依赖管理统一维护Netty版本(默认4.1.100.Final),手动引入netty-all会引发版本冲突,直接删除该依赖:
<!-- 删除此依赖 --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>${netty.version}</version> </dependency>
2. 恢复spring-boot-starter-data-redis的Netty依赖排除
手动排除Netty核心依赖会导致类缺失或版本不一致,移除这些排除项:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <!-- 删除以下exclusions块 --> <!-- <exclusions> <exclusion> <groupId>io.netty</groupId> <artifactId>netty-common</artifactId> </exclusion> <exclusion> <groupId>io.netty</groupId> <artifactId>netty-handler</artifactId> </exclusion> <exclusion> <groupId>io.netty</groupId> <artifactId>netty-transport</artifactId> </exclusion> </exclusions> --> </dependency>
3. 替换macOS不支持的Epoll配置
Epoll是Linux专属通道选项,macOS需使用KQueue,修改HttpClient配置中的Epoll相关选项:
// 替换前 .option(EpollChannelOption.TCP_KEEPIDLE, 300) .option(EpollChannelOption.TCP_KEEPINTVL, 60) // 替换后(引入KQueueChannelOption) .option(KQueueChannelOption.TCP_KEEPIDLE, 300) .option(KQueueChannelOption.TCP_KEEPINTVL, 60)
若需跨平台兼容,可直接移除这些系统专属选项,让Reactor Netty自动适配。
4. 统一Netty Native依赖版本
确保netty-transport-native-kqueue版本与Spring Boot管理的Netty版本一致,删除手动指定的版本,交由依赖管理自动处理:
<dependency> <groupId>io.netty</groupId> <artifactId>netty-transport-native-kqueue</artifactId> <!-- 删除version属性 --> <classifier>osx-x86_64</classifier> </dependency>
同时netty-tcnative和netty-tcnative-boringssl-static版本需与Netty核心版本匹配,推荐使用Spring Boot提供的版本变量。
5. 清理并重新构建项目
执行以下Maven命令清理本地依赖并重新构建,确保所有依赖版本统一:
mvn clean install -U
内容的提问来源于stack exchange,提问作者user27630372
相关产品推荐
相关产品推荐

