解决Spring Boot中使用Undertow时启动有警告日志的问题

使用 Undertow 作为 Servlet 容器

Spring Boot 默认使用Tomcat作为 Servlet 容器,但Undertow以其出色的性能逐渐获得了更多用户的青睐。

要在 Spring Boot 中使用 Undertow 代替 Tomcat,只需要把 spring-boot-starter-tomcatspring-boot-starter-web starter 中排除,并添加spring-boot-starter-undertow 依赖即可。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

使用Undertow后,启动应用,你应该可以看到一条警告日志。


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.4)

...
2022-10-17 11:24:33.234  WARN 13748 --- [           main] io.undertow.websockets.jsr               : UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
...

2022-10-17 11:24:33.234 WARN 13748 — [ main] io.undertow.websockets.jsr : UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used

显然,此警告的原因是某些东西没有设置,系统使用了默认设置。

解决方案1,设置WebSocketDeploymentInfo属性

只要通过 WebServerFactoryCustomizer 配置类为 io.undertow.websockets.jsr.WebSocketDeploymentInfo 属性手动设置一个合理的值即可。

import io.undertow.server.DefaultByteBufferPool;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;

import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UndertowServletWebServerFactoryConfiguration implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {

    @Override
    public void customize(UndertowServletWebServerFactory factory) {
        
        factory.addDeploymentInfoCustomizers(deploymentInfo -> {
            
            WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
            webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 4096));

            deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
        });
    }
}

解决方案2,直接排除 undertow-websockets-jsr 依赖

如果你的应用程序不使用websocket相关的东西,你可以直接从 spring-boot-starter-undertow 中排除 undertow-websockets-jsr 依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
    <!-- 排除 undertow-websockets-jsr 依赖-->
    <exclusions>
        <exclusion>
            <groupId>io.undertow</groupId>
            <artifactId>undertow-websockets-jsr</artifactId>
        </exclusion>
    </exclusions>
</dependency>

经过验证,上述2种方式都有效。

参考: