我在这里写这篇文章是因为我找不到问题的解决方案。我有一个 Spring Boot 应用程序,部署在外部 tomcat 版本 10.1.6 上。因此,为了在本地和生产环境中使用相同的 tomcat 版本,我在 build.gradle 上设置了 Tomcat 版本,extra["tomcat.version"] = "10.1.6"。但当我这样做时,应用程序无法启动:
Spring Boot 版本:3.3.4
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.boot.autoconfigure.web.embedded.TomcatWebServerFactoryCustomizer.customizeMaxQueueCapacity(TomcatWebServerFactoryCustomizer.java:170)
The following method did not exist:
'void org.apache.coyote.AbstractProtocol.setMaxQueueSize(int)'
The calling method's class, org.springframework.boot.autoconfigure.web.embedded.TomcatWebServerFactoryCustomizer, was loaded from the following location:
jar:file:/Users/USER/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-autoconfigure/3.3.4/979234a0f3035fe60d5e505018789f98a7ec7ee3/spring-boot-autoconfigure-3.3.4.jar!/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.class
The called method's class, org.apache.coyote.AbstractProtocol, is available from the following locations:
jar:file:/Users/USER/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-core/10.1.6/abacfdcc788fafbf671c6f68338bd2d5c27411e7/tomcat-embed-core-10.1.6.jar!/org/apache/coyote/AbstractProtocol.class
The called method's class hierarchy was loaded from the following locations:
org.apache.coyote.AbstractProtocol: file:/Users/USER/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-core/10.1.6/abacfdcc788fafbf671c6f68338bd2d5c27411e7/tomcat-embed-core-10.1.6.jar
Action:
Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.boot.autoconfigure.web.embedded.TomcatWebServerFactoryCustomizer and org.apache.coyote.AbstractProtocol
Process finished with exit code 1
为了解释我的问题,我使用 Spring Initializr 创建了一个示例项目:https ://github.com/amourier63/spring-boot-set-tomcat-version
在 Build.gradle.kts 第 23 行。如果我注释掉该行并启动项目,项目就会启动。但是当我取消注释时,启动失败。
我接受任何建议...也许设置 tomcat 版本是个坏主意。
谢谢
该
AbstractProtocol.setMaxQueueSize()
方法是 Apache Tomcat v10.1.25(源server.tomcat.threads.max-queue-capacity
)中引入的,并且在配置后立即设置(并且该属性具有默认值)。简而言之,Spring Boot v3.3.4 与 Apache Tomcat v10.1.6 不兼容。
可能的解决方案包括:
将外部 Tomcat 更新到 v10.1.25 或更高版本(我建议升级到最新的 v10.1.x 或 v10.1.30,因为这是 Spring Boot v3.3.4 默认使用的版本)。
或者,你可以将设置
server.tomcat.threads.max-queue-capacity
为非正值,因为在这种情况下TomcatWebServerFactoryCustomizer
不会调用setMaxQueueSize()
方法(source)。但我不建议这样做。将 Spring Boot 降级到 v3.3.0。此功能是在 Spring Boot v3.3.1 中引入的(请参阅问题),因此降级到 v3.3.0 不会导致此错误发生。我也不建议这样做。
由于错误仅发生在嵌入式 Tomcat 配置中(我假设您使用它进行开发?),您还可以删除该
<tomcat.version>
属性并在最新支持的 Tomcat 10.1.x 版本上本地运行,同时在 Tomcat 10.1.6 上部署 WAR 文件。