SpringBoot版本升级引起的FileNotFoundException——WebMvcConfigurerAdapter.class

这篇具有很好参考价值的文章主要介绍了SpringBoot版本升级引起的FileNotFoundException——WebMvcConfigurerAdapter.class。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

缘起

最近公司项目要求JDK从8升到17,SpringBoot版本从2.x升级到3.x,期间遇到了一个诡异的FileNotFoundException异常,日志如下(敏感信息使用xxx脱敏)

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.xxx.xxx.OperationAnalysisApplication]
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:179)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:397)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:283)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:344)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:115)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:745)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:565)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)
	at com.xxx.xxx.OperationAnalysisApplication.main(OperationAnalysisApplication.java:34)
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.class] cannot be opened because it does not exist
	at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:211)
	at org.springframework.core.type.classreading.SimpleMetadataReader.getClassReader(SimpleMetadataReader.java:54)
	at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:48)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103)
	at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:86)
	at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:73)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81)
	at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:611)
	at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getSuperClass(ConfigurationClassParser.java:924)
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:335)
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:244)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:189)
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:298)
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:244)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:197)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:165)
	... 13 common frames omitted

SpringBoot3.x已经删除了类WebMvcConfigurerAdapter,建议实现接口WebMvcConfigurer

过程

1. 查找当前项目中使用WebMvcConfigurerAdapter的地方

这个报错日志明显没有提示出哪个类有问题,先排除当前项目自己写的代码有没有这个类,于是在IDEA中使用全局查找来查找使用WebMvcConfigurerAdapter的地方,发现都被WebMvcConfigurer接口替代了,看来并不是自己写的代码里面的,二是某个Jar中的,这大概就是没有显示因为哪个类继承了WebMvcConfigurerAdapter导致异常的原因吧

2. 查找哪个Jar中引用了这个类

下个断点看看

这TM和大海捞针没区别啊,这项目光依赖自己的包就几十个,大部分都是公司内部包,我都没有源码,这可怎么找啊,只能去报异常的地方碰碰运气了。我找到了报异常的地方:
日志显示在这

at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:211)

源码如下:

public InputStream getInputStream() throws IOException {
   InputStream is;
    if (this.clazz != null) {
        is = this.clazz.getResourceAsStream(this.path);
    } else if (this.classLoader != null) {
        is = this.classLoader.getResourceAsStream(this.absolutePath);
    } else {
        is = ClassLoader.getSystemResourceAsStream(this.absolutePath);
    }

    if (is == null) {
        throw new FileNotFoundException(this.getDescription() + " cannot be opened because it does not exist");
    } else {
        return is;
    }
}

报异常的地方很明显了,就是这

 if (is == null) {
     throw new FileNotFoundException(this.getDescription() + " cannot be opened because it does not exist");
 }

在这里下断点,启动项目,发现这个类里this.clazz是null,this.classLoader不是null,感觉这个classloader应该就是加载某个类的时候发现它的父类是WebMvcConfigurerAdapter,去加载WebMvcConfigurerAdapter找不到才报错的。就去这个classloader里面翻找了一下,感觉最有价值的就是里面的classes属性了,如下:
SpringBoot版本升级引起的FileNotFoundException——WebMvcConfigurerAdapter.class,spring boot,后端,java

当前实例中的classes中找找

里面居然已经加载了5285个类,一个一个的看显然不行,于是在classes上右键,然后选择评估表达式,想着这个classes是个ArrayList,使用classes.stream().filter()筛选一下加载的类里面是否有父类是WebMvcConfigurerAdapter的,找到了不就知道是哪个有问题了么。写好筛选条件后执行,报错如下:
SpringBoot版本升级引起的FileNotFoundException——WebMvcConfigurerAdapter.class,spring boot,后端,java
这…大概是JDK里面很多类还没加载导致的吧,看来这条行不通了。于是考虑这个classesArrayList类型,有序列表啊,其中最后一个元素有没有可能是当前继承了WebMvcConfigurerAdapter的类么?于是使用评估表达式获取了最后一个元素,很遗憾,是个idea的类:
SpringBoot版本升级引起的FileNotFoundException——WebMvcConfigurerAdapter.class,spring boot,后端,java
梦想再一次破灭了。

是不是当前类加载器能提供点什么信息

想着是不是当前类加载器能看到当前在加载哪个类或者哪个类的加载引起了当前类的加载啊?很遗憾,classloader根本没有这信息,只有当前类加载器正在加载的这个类WebMvcConfigurerAdapter

看看谁触发了当前类加载

很遗憾,上面的方法都没找到很有用的信息,于是想着,看看谁调用了当前方法,也就是说谁触发了加载WebMvcConfigurerAdapter这个类的动作,于是顺着调用栈:
SpringBoot版本升级引起的FileNotFoundException——WebMvcConfigurerAdapter.class,spring boot,后端,java
一直往回找,终于,在下面这个地方找到了:
SpringBoot版本升级引起的FileNotFoundException——WebMvcConfigurerAdapter.class,spring boot,后端,java
这里点开resource字段,直接定位到类:

import com.xxx.data.analytics.interceptor.RequestDataInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
    public InterceptorConfig() {
    }

    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RequestDataInterceptor()).addPathPatterns(new String[]{"/**"});
        super.addInterceptors(registry);
    }
}

就是这了。
Jar里面没法排掉某个特定的类,只能在当前项目中创建一个和这个类一模一样的类,代码改成自己想要的。因为Java中,某个类(同一个classloader+全限定名)已经被加载了,就不会再次被加载,项目中的类加载优先于Jar包中的,又都是同一个类加载器加载,所以会优先加载到项目中类,Jar中的则不会被加载了,曲线救国 我试了下似乎不行,待考证,暂时先加删除线,后续会回来看看怎么解决这个问题。
-------------------------------------------------------->分割线20230729<------------------------------------------------------------------------------
最后在项目里创建了一个package :org.springframework.web.servlet.config.annotation然后把WebMvcConfigurerAdapter拷贝进来,把InterceptorConfig 在SpringBoot启动类上设置为不扫描,把问题解决了。不创建包org.springframework.web.servlet.config.annotation并拷贝WebMvcConfigurerAdapter直接在SpringBoot启动类上设置为不扫描是不行的,因为你设置InterceptorConfig 不扫描时JVM会首先加载这个类,这个类有父类就先尝试加载父类WebMvcConfigurerAdapter,父类不存在,直接报错。文章来源地址https://www.toymoban.com/news/detail-615010.html

到了这里,关于SpringBoot版本升级引起的FileNotFoundException——WebMvcConfigurerAdapter.class的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PyMySQL库版本引起的python执行sql编码错误

    长话短说,之前在A主机(centos7.9)上运行的py脚本拿到B主机上(centos7.9)运行报错: 两个主机系统、python版本、pip版本都是相同的。但是在B主机执行py脚本时,报错指向的代码就是 sql 语句,sql语句也就是一串字符串啊; py脚本是定时任务,使用pymysql库连接环境内的mysql执行

    2024年02月14日
    浏览(35)
  • 由于 vscode 版本更新为 1.86.1引起的相关问题。

    通过vscode ssh来远程连接linux服务器的代码,由于vscode 1.86.1的更新,在连接服务器时就开始报 两个错误了:   Missing GLIBCXX = 3.4.25! Missing GLIBC = 2.28! lwd@192.168.66.148\\\'s password: 075b6e8e3a87: running Missing GLIBCXX = 3.4.25! Found versions 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 3.4.8 3.4.9 3.4.10 3.4.11 3.4.1

    2024年02月21日
    浏览(45)
  • jQuery版本低引起的漏洞——CVE-2020-11022/CVE-2020-11023

    漏洞号: CVE-2020-11022 / CVE-2020-11023 影响范围:jQuery = 1.0.3 3.5.0 漏洞原理 见:jQuery最新xss漏洞分析——CVE-2020-11022/11023 - 云+社区 - 腾讯云 (tencent.com) 漏洞复现 https://vulnerabledoma.in/jquery_htmlPrefilter_xss.html 要想在项目本地实现,可把该html保存下来,修改script的src属性为项目引用j

    2023年04月26日
    浏览(42)
  • JCE cannot authenticate the provider BC因jdk版本引起的加密包报错

    原因: 高版本的jdk引起的加密包报错,可以编译代码,然后找到bcprov-jdk高版本的jar包,复制到java/jdk版本号/jre/lib/ext目录下 目前我的java版本是1.8.0_391 如果不行,需要修改Javajdk-1.8jrelibsecurity目录下java.security文件 添加security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvide

    2024年02月04日
    浏览(42)
  • WebMvcConfigurerAdapter

    WebMvcConfigurerAdapter 是Spring 3.1到Spring 5.0版本中用于自定义Spring MVC配置的一个便捷适配器类。在Spring 5.0及之后的版本中,WebMvcConfigurerAdapter 已经被标记为过时(deprecated),并且官方推荐直接实现 WebMvcConfigurer 接口。不过,对于老版本的Spring来说,WebMvcConfigurerAdapter 提供了一个

    2024年01月22日
    浏览(31)
  • 79、SpringBoot 整合 R2DBC --- R2DBC 就是 JDBC 的 反应式版本, R2DBC 是 JDBC 的升级版。

    R2DBC 就是 JDBC 的 反应式版本, R2DBC 是 JDBC 的升级版。 R2DBC 是 Reactive Relational Database Connectivity (关系型数据库的响应式连接) 的缩写 反应式的就是类似于消息发布者和订阅者,有消息就进行推送。R2DBC中DAO接口中方法的返回值是 Flux 或 Mono 因此,反应式的 R2DBC ,是不存在 【分

    2024年02月07日
    浏览(49)
  • 升级php版本(简单明了,轻松升级php任意版本)

    1、查看当前php版本 2、查看当前所有php安装包 查看是否有你需要的版本,如果没有: 使用 Remi 存储库:Remi 存储库是一个第三方存储库,提供了广泛的 PHP 版本和扩展包。你可以按照以下步骤安装并启用 Remi 存储库: 3、查看是否升级

    2024年04月26日
    浏览(42)
  • MacOS 升级golang版本后无法debug,升级delve版本

    golang版本升级到1.20以后导致debug失效了,本文针对MacOS系统,win系统也可作参考。 1、升级delve版本 安装完后,测试版本 2、进入brew的安装目录,找到dlv的二进制文件 我的是1.8.版本所以目录是 看到有个dlv的二进制文件,拷贝这个文件放到下一步goland目录下。 3、goland的plugin目

    2024年02月12日
    浏览(57)
  • DolphinScheduler2.0版本升级3.0版本方案

    因项目需要使用数据质量模块功能,可以为数仓提供良好的数据质量监控功能。故要对已有2.0版本升级到3.0版本以上,此次选择测试了3.0.1 和 3.1.1 两个版本,对进行同数据等任务调度暂停等操作测试,最后选择3.0.1 版本 原因: 1. 3.1.1 在测试sql任务时 ,同时启动上百sql 任务

    2024年02月09日
    浏览(42)
  • python从就旧版本升级到3.8版本

    用yum或者其它包管理器安装的py太旧了,大概是3.6版本,新版本官网上没有编译好的。现在把编译步骤记录下来方便以后使用。 1.下载 wget https://www.python.org/ftp/python/3.8.18/Python-3.8.18.tgz, tar -xvf Python-3.8.18.tgz 2.编译 cd Python-3.8.18 ./configure --prefix=/usr/local/python3.8.18 make make install 3.更

    2024年02月03日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包