解决Spring Cloud Gateway依赖冲突

6,880 阅读2分钟

spring-boot-start-web依赖

启动报错

第一次启动网关项目项目时报错,错误信息如下:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method modifyRequestBodyGatewayFilterFactory in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' that could not be found.


Action:

Consider defining a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' in your configuration.

错误分析

根据上面描述(Description)中信息了解到GatewayAutoConfiguration这个配置中找不到ServerCodecConfig这个Bean。

而网关项目是一个spring boot项目,在启动的时候会去加载它的配置,其中有一个叫做GatewayClassPathWarningAutoConfiguration的配置类中有这么一行代码:

@Configuration
@ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")
protected static class SpringMvcFoundOnClasspathConfiguration {

    public SpringMvcFoundOnClasspathConfiguration() {
        log.warn(BORDER+"Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway at this time. " + "Please remove spring-boot-starter-web dependency."+BORDER);
    }
}

log.warn中翻译一下意思就是“在类路径上找到的Spring MVC,此时它与Spring Cloud网关不兼容。请删除spring-boot-start-web依赖项。”。

解决方案

排除spring-boot-starter-web依赖。

再次启动,果然成功了。O(∩_∩)O哈哈~

非spring-boot-start-web依赖

添加数据库相关依赖后启动报错

昨天在整合OAuth2.0时,因为需要保存token到数据库,于是添加了以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<!-- druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
</dependency>

启动项目时报错:

05-06 11:57:08.590 ERROR o.s.boot.SpringApplication [826] Application run failed
java.lang.NoClassDefFoundError: javax/servlet/Servlet
	at java.lang.Class.getDeclaredConstructors0(Native Method)
	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
	at java.lang.Class.getDeclaredConstructors(Class.java:2020)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBindConstructorProvider.findConstructorBindingAnnotatedConstructor(ConfigurationPropertiesBindConstructorProvider.java:62)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBindConstructorProvider.getBindConstructor(ConfigurationPropertiesBindConstructorProvider.java:48)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBean$BindMethod.forType(ConfigurationPropertiesBean.java:311)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBeanDefinitionValidator.validate(ConfigurationPropertiesBeanDefinitionValidator.java:63)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBeanDefinitionValidator.postProcessBeanFactory(ConfigurationPropertiesBeanDefinitionValidator.java:45)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:286)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:174)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
	at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
	at com.ileadtek.gateway.CpGatewayApplication.main(CpGatewayApplication.java:18)
Caused by: java.lang.ClassNotFoundException: javax.servlet.Servlet
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	... 19 common frames omitted

发现是因为Druid依赖于javax.servlet-api

1、Druid依赖javax.servlet-api.jpg

但在我添加servlet依赖后又报错:

2、依赖javax.servlet-api后启动报错.jpg

接着添加tomcat-embed-core依赖来解决以上错误,再次启动后发现又出现了之前遇到过的jar包冲突问题:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method modifyRequestBodyGatewayFilterFactory in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' that could not be found.


Action:

Consider defining a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' in your configuration.

好嘞,排除spring-boot-starter-web依赖肯定行的啦( ̄▽ ̄)/ 但是。。。我好想没发现哪个项目有依赖spring-boot-starter-web呀!

是它!Druid的问题

我又排除了好几个依赖项,最终才定位到是Druid的问题,最根本的原因是它间接依赖了tomcat-embed-core,无奈之下只好换数据源了:

4、更换数据源.jpg

再次启动,果然成功了。O(∩_∩)O哈哈~

总结

看来spring-cloud-starter-gateway并非是spring-boot-starter-web的原因,我发现spring-boot-starter-web也依赖了tomcat-embed-core。

5_原因.jpg

所以我认为最根本的还是因为项目中tomcat-embed-core依赖包(* ̄︶ ̄)

参考

www.codeleading.com/article/651…

如果大家也遇到了这个问题,欢迎一起交流哦(#^.^#)