Spring Boot 3 Native Image启动失败:缺少ServletWebServerFactory Bean
问题
将复杂Spring Boot应用升级至Boot 3.0和Cloud 2022.0.0-SNAPSHOT,相关Gradle依赖配置如下:
plugins { id("org.springframework.boot") version "3.0.0" id("io.spring.dependency-management") version "1.1.0" id("com.github.davidmc24.gradle.plugin.avro") version "1.5.0" jacoco kotlin("jvm") version "1.7.21" kotlin("plugin.spring") version "1.7.21" id("org.graalvm.buildtools.native") version "0.9.19" } java.sourceCompatibility = VERSION_17 repositories { maven { url = uri("https://repo.spring.io/milestone") } maven { url = uri("https://repo.spring.io/snapshot") } mavenCentral() maven { url = uri("https://packages.confluent.io/maven") } maven { url = uri("https://oss.jfrog.org/artifactory/oss-snapshot-local") } } extra["springCloudVersion"] = "2022.0.0-SNAPSHOT" extra["confluentVersion"] = "7.3.0" extra["avroVersion"] = "1.11.1" dependencies { implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-actuator") implementation("org.springframework.cloud:spring-cloud-starter-kubernetes-fabric8-config") implementation("org.springframework.boot:spring-boot-starter-data-mongodb") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("org.springframework.cloud:spring-cloud-starter-bootstrap") implementation("org.springframework.cloud:spring-cloud-stream") implementation("org.springframework.cloud:spring-cloud-stream-binder-kafka-streams") implementation("io.micrometer:micrometer-tracing-bridge-brave") implementation("io.confluent:kafka-avro-serializer:${property("confluentVersion")}") implementation("io.confluent:kafka-schema-registry-client:${property("confluentVersion")}") implementation("io.confluent:kafka-streams-avro-serde:${property("confluentVersion")}") implementation("org.apache.avro:avro:${property("avroVersion")}") implementation("io.micrometer:micrometer-registry-prometheus") implementation("io.projectreactor.kotlin:reactor-kotlin-extensions") implementation("javax.money:money-api:1.1") implementation("org.javamoney:moneta:1.4.2") implementation("com.atlassian.commonmark:commonmark:0.17.0") }
执行命令./gradlew clean bootBuildImage生成Native Image后,通过以下命令启动容器:
docker run -p 8080:8080 -e SPRING_PROFILES_ACTIVE=local,confluent-cloud docker.io/library/myapp:2.0.0-SNAPSHOT
启动失败,报错信息如下:
2022-12-15T20:12:25.981Z INFO [,,] 1 --- [ main] i.s.m.MyAppKt : Starting AOT-processed MyAppKt using Java 17.0.5 with PID 1 (/workspace/i.s.m.MyAppKt started by cnb in /workspace) 2022-12-15T20:12:25.981Z INFO [,,] 1 --- [ main] i.s.m.MyAppKt : The following 2 profiles are active: "local", "confluent-cloud" 2022-12-15T20:12:25.985Z WARN [,,] 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server 2022-12-15T20:12:25.985Z ERROR [,,] 1 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLICATION FAILED TO START *************************** Description: Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.
请问该问题的原因是什么?
原因分析
这个问题的核心是Spring Native AOT处理时,Web相关的自动配置未被正确触发,导致容器启动时找不到ServletWebServerFactory bean,具体原因如下:
Spring Cloud Bootstrap与Native Image的兼容性问题:引入的
spring-cloud-starter-bootstrap在Spring Boot 3.0+搭配Spring Cloud 2022.0.x快照版本中,Bootstrap上下文的初始化逻辑在AOT处理阶段未正确包含Web自动配置类,使得Web服务器工厂bean无法被注册。AOT元数据缺失:生成Native Image时,Spring会提前执行AOT分析来确定需要打包的类和bean。如果Web相关的自动配置(如
TomcatServletWebServerFactoryAutoConfiguration)未被AOT工具识别为必要配置,生成的Native Image中就不会包含对应的ServletWebServerFactorybean定义。激活的配置文件影响:启动时激活的
local和confluent-cloud配置文件中,可能存在配置项意外关闭了Web自动配置,或者覆盖了Spring Boot默认的Web相关配置,导致AOT处理时跳过了Web服务器的自动配置流程。
此外,Spring Cloud 2022.0.x(代号Kilburn)处于快照阶段,部分组件的Native Image支持尚未完善,尤其是Bootstrap上下文与Web自动配置结合的场景,容易出现这类bean缺失问题。
内容的提问来源于stack exchange,提问作者codependent

