You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 19:47:31