目录

一、问题描述及产生原因:

二、相关异常 

三、问题排查思路:

1、首先找到出现冲突的jar分别是哪个包的依赖? 只知道要排除spring-boot-starter-web怎么找到这个jar所在的组件位置呢?

2、找到了冲突jar的位置,如何排除?:

3、重新加载pom文件和更新jar包,观察pom依赖关系图的变化:

 4、重启项目


一、问题描述及产生原因:

异常:

Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency

      通过百度异常,大家都知道, 在springboot整合gateway时, gateway组件中的 【spring-boot-starter-webflux】 和 springboot作为web项目启动必不可少的 【spring-boot-starter-web】 出现冲突。

解决方案很简单,及排除两个中的一个即可。

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

二、相关异常 

针对gateway和springboot的整合, 两个冲突的包必须存在一个 【spring-boot-starter-webflux】、【spring-boot-starter-web】,否则会报下面的错:

Description:
 
Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.
 
Action:
 
Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.

两个冲突的包又必须不能同时存在 【spring-boot-starter-webflux】、【spring-boot-starter-web】,否则会报下面的错:

Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency

建议留下webflux的包,毕竟gateway和zuul的区别就在于额外集成了webflux

以上是解决方案,满足大部分人需求,但非本文讨论重点、本文重点在于记录如何排查解决这个问题, 同理、如何解决其它jar包冲突的问题,毕竟已经花了几个小时摸索,记录下来以备不时之需,同时分享给和我一样正在苦苦摸索前进的人。

三、问题排查思路:

1、首先找到出现冲突的jar分别是哪个包的依赖? 只知道要排除spring-boot-starter-web怎么找到这个jar所在的组件位置呢?

作者本人的项目中有两处产生了这个jar的依赖,根据idea提供的pom依赖关系图(依赖关系图查看方式:打开pom文件,右键点击,或快捷键 ctrl+alt+shift+u 或 出门百度)可以看到,我的项目两个地方提供:

 分别根据来源的箭头指向查到两个包的来源为:

和: 

 双击名称分别发现,两个jar存在与父类项目中。

2、找到了冲突jar的位置,如何排除?:

我分析了大家可能有以下情况:

        1、jar存在于同级其它项目  如common包中  (在引入项目包的地方排除)
        2、jar存在于父类maven中 (详解)

        3、jar存在于当前项目的其它组件中     (在引入组件包的地方排除)

        4、欢迎补充···

作者遇到的情况是 (2):

那么通过学习maven知识我们知道,如果父类将依赖设定在 <dependencies> 中,则表示子model不需要重新引用即可直接使用,如果依赖设定在<dependencyManagement> 标签中 ,则表示子model必须重新引用,才可以使用,但是父项目一般设置好了版本号等,不重写版本号则默认使用父类的,如果重写版本号则使用自己定义的。

作者的项目背景中父项目是使用的<dependencies>  即子类不需要引用就存在这个jar,考虑其它子项目也在用父类的包,直接在父类项目上修改的方式肯定是下下策。
我考虑通过重写的方式,不修改父类,不影响其它子项目,在gateway 子项目中重新引用父类的这两个jar,然后再 exclusion 排除其中的冲突jar。

父项目引用的组件:

 子项目重写并排除:

3、重新加载pom文件和更新jar包,观察pom依赖关系图的变化:

打开pom > ctrl+alt+shift+u > ctrl+f 查询 搜索 web (如果ctrl+f 查询的结果不能直接定位到,就重新打开依赖关系图)

 发现已经没有了start-web 这个jar的依赖了 , 说明我们排除成功了

【注意】如果你通过查询发现还是存在,那么继续往下看:

    首先分析没有成功的原因,是否是jar更新失败, 通常我们使用 idea的插件更新及点击这个小刷新按钮,但是失败的教训告诉我,点击这个按钮没有详细的反馈结果不知道是成功了还是没成功,我就是这里没成功,以为是没生效,排查了很久。

建议通过maven命令的方式去更新依赖, 在项目根路径下,执行 mvn clean 、 mvn install 看结果是否成功,如果失败是哪里失败。 (失败报错情况的有很多,根据报错自行百度)

另外,更新的时候,因为子项目依赖的父项目,先更新父项目依赖,更新完后在更新子项目(网关项目的依赖)否则可能还是旧的jar 
 然后观察依赖关系图,依赖是否去掉。

 4、重启项目

启动成功。


至此,本次问题的排查过程记录完毕,自己已经两次花时间在这个问题上面了,所以总结记录一下,希望对你也有帮助,希望大家能和心静气的提出改进意见。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐