illegalstateexception是什么异常_异常源码分析—告诉你学习“源码”究竟有什么用!...
点击上方“服务端思维”,选择“设为星标”
回复”669“获取独家整理的精选资料集
回复”加群“加入全国服务端高端社群「后端圈」
一、引言
最近接了个相当于外包的项目,在他们项目中集成一个WebSocket的服务端,嗯功能其实不难,但是前方有坑。
本文主要来记录一下,如果没有了百度,在项目启动就抛异常、或者一些奇奇怪怪的问题,靠自己怎么去排查问题,同样有时候并不是所有的问题都能够通过搜索引擎来解决。
除了外力,那我们就只剩下:异常信息、源码、和本身经验。
项目框架用的是SpringBoot,然后集成WebSocket就行,在集成的过程中,其中有一步需要配置一个Bean。
@Componentpublic class WsConfig {
@Bean public ServerEndpointExporter serverEndpointExporter() { ServerEndpointExporter serverEndpointExporter = new ServerEndpointExporter(); return serverEndpointExporter; }
然后在项目启动的时候抛出了异常信息:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverEndpointExporter' defined in class path resource [org/springblade/modules/hol/config/WsConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1769) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:514) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:321) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:319) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:863) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140) at org.springblade.core.launch.BladeApplication.run(BladeApplication.java:50) at org.springblade.Application.main(Application.java:18)Caused by: java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available at org.springframework.util.Assert.state(Assert.java:73) at org.springframework.web.socket.server.standard.ServerEndpointExporter.afterPropertiesSet(ServerEndpointExporter.java:107) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1828) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1765) ... 16 common frames omitted
二、问题分析
Error creating bean with name 'serverEndpointExporter' defined in class path resource [org/springblade/modules/hol/config/WsConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
通过异常的第一行就能够得知,是在Spring创建“serverEndpointExporter”bean的时候抛出来的,是这个WsConfig类,原因是:ServerContainer这个对象不可使用。
抛出异常的类是:AbstractAutowireCapableBeanFactory.java:1769
分析到这里就能够得知,是在spring创建serverEndpointExporter的时候异常了,那么异常的原因是什么呢?,为什么ServerContainer不可用呢? 接着分析
通过控制台点击到对应的源码信息如下:AbstractAutowireCapableBeanFactory.java:1769
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( // 1769 这里就是1769行~~ (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
通过查看源码,是在1796行的catch里面抛出的异常的,catch是捕捉到invokeInitMethods这个方法异常,然后才抛出来的,这样就可以开始进行Debug了。
既然是在创建serverEndpointExporter这个bean异常的,加一个筛选条件,beanName等于serverEndpointExporter,这样就能过滤创建的其他bean。
断点卡好了,接下来就Debug模式来启动项目,然后F5进到invokeInitMethods方法,单步往下执行。
最后执行到了 ((InitializingBean) bean).afterPropertiesSet(); 这行代码,bean对象是ServerEndpointExporter,调用了这个对象的afterPropertiesSet方法。
来到ServerEndpointExporter这个java类,其中就会有afterPropertiesSet方法,首先调用getServerContainer方法获取serverContainer对象。
很明显这里返回的肯定是null,null != null 结果肯定是false,最后就是这样调用state(false,javax.websocket.server.ServerContainer not available)
通过state源码得知,最后就会抛出这个异常:java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
三、解决问题
通过文章上述分析,可以确认是因为ServerEndpointExporter这个类中有一个对象叫做serverContainer,它为null了,所以才会异常。
接下来我们就需要去找,serverContainer这个对象是在哪里赋值的,找源码就只有两处赋值了,这就好办了。
public class ServerEndpointExporter extends WebApplicationObjectSupport implements InitializingBean, SmartInitializingSingleton {
@Nullable private List> annotatedEndpointClasses; @Nullable private ServerContainer serverContainer; // 有一个Set方法可以为serverContainer赋值 public void setServerContainer(@Nullable ServerContainer serverContainer) { this.serverContainer = serverContainer; } @Nullable protected ServerContainer getServerContainer() { return this.serverContainer; } // 有一个init方法可以为serverContainer赋值 @Override protected void initServletContext(ServletContext servletContext) { if (this.serverContainer == null) { this.serverContainer = (ServerContainer) servletContext.getAttribute("javax.websocket.server.ServerContainer"); } } @Override public void afterPropertiesSet() { Assert.state(getServerContainer() != null, "javax.websocket.server.ServerContainer not available"); } }
通过IDEA的快捷方式,发现没有其他地方调用了setServerContainer方法,那么就只有init方法了,那么就把断点卡在initServletContext方法这。
通过Bebug就能够发现,在从servletContext.getAttribute的时候,根本就没有javax.websocket.server.ServerContainer,所以getAttribute返回就是一个null,最后赋值给了serverContainer,最后就导致异常了。
那为什么javax.websocket.server.ServerContainer会不存在呢?
来到这个ServerContainer对应的java类,原来是一个interface,那必然就会有对应的实现类,通过IDEA查看好家伙,到这小编大概就明白了,这个项目引用了其他jar包,导致了冲突。
最后定位到是哪个jar冲突了,直接通过IDEA定位功能就能够定位到,最后通过maven helper工具定位到maven引用位置,然后移除掉。
最后刷新一下maven,项目就能够正常启动啦~~~~~
四、划重点
本文并不是针对某一个异常、或者某一个具体的问题来进行分析,而是分享一下解决这个异常的一个过程。
最初的小编刚毕业那会,遇到个异常就百度,运气好的话,很多人都踩过这个坑,能够解决,万一恰好没有找到合适的文章,然后、然后就陷入了沉思,也不知道咋办。
而且通过别人来解决的问题,肯定没有自己解决问题的印象深刻,而且通过自己去找问题也是个有趣的过程。
也有很多小伙伴问过小编,学习一些框架源码有什么用?会用不就行了吗?
怎么说呢?当然确实会用就行了,话又说话来,难道你就不好奇它们这些技术到底是怎么实现的吗?看源码不仅仅能够学习到其他大神编写代码的风格,而且对于使用也有会更加深一层次的理解。
久而久之,遇到问题,你的第一反应并不是直接去百度,而是会自己主动去摸索,到底是为啥子异常的,碰到一些看不懂的源码,再去百度学习一下,进行分析。
就这样不知不觉你的技术就会慢慢得到升华,那个时候感觉就特别明显了。
— 本文结束 —
● 漫谈设计模式在 Spring 框架中的良好实践
● 颠覆微服务认知:深入思考微服务的七个主流观点
● 人人都是 API 设计者
● 一文讲透微服务下如何保证事务的一致性
● 要黑盒测试微服务内部服务间调用,我该如何实现?
关注我,回复 「加群」 加入各种主题讨论群。
对「服务端思维」有期待,请在文末点个在看
喜欢这篇文章,欢迎转发、分享朋友圈
在看点这里
illegalstateexception是什么异常_异常源码分析—告诉你学习“源码”究竟有什么用!...相关推荐
- 【OkHttp】OkHttp 源码分析 ( OkHttpClient.Builder 构造器源码分析 )
OkHttp 系列文章目录 [OkHttp]OkHttp 简介 ( OkHttp 框架特性 | Http 版本简介 ) [OkHttp]Android 项目导入 OkHttp ( 配置依赖 | 配置 ...
- 【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )
Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...
- 【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 )
Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...
- Flume 1.7 源码分析(一)源码编译
Flume 1.7 源码分析(一)源码编译 Flume 1.7 源码分析(二)整体架构 Flume 1.7 源码分析(三)程序入口 1 说明 Flume是Cloudera提供的一个高可用的,高可靠的, ...
- Storm源码分析之四: Trident源码分析
Storm源码分析之四: Trident源码分析 @(STORM)[storm] Storm源码分析之四 Trident源码分析 一概述 0小结 1简介 2关键类 1Spout的创建 2spout的消 ...
- 【SemiDrive源码分析】【Yocto源码分析】02 - yocto/meta-openembedded目录源码分析
[SemiDrive源码分析][Yocto源码分析]02 - yocto/meta-openembedded目录源码分析 一.meta-openembedded 目录 本 SemiDrive源码分析 ...
- 嵌入式之uboot源码分析-启动第二阶段学习笔记(下篇)
接上部分---->嵌入式之uboot源码分析-启动第二阶段学习笔记(上篇) 注:如下内容来自朱老师物联网大讲堂uboot课件 3.2.14 CFG_NO_FLASH (1)虽然NandFlash ...
- 【SemiDrive源码分析】【Yocto源码分析】07 - core-image-base-x9h_ref_serdes.rootfs.ext4 文件系统是如何生成的
[SemiDrive源码分析][Yocto源码分析]07 - core-image-base-x9h_ref_serdes.rootfs.ext4 文件系统是如何生成的 1.core-image-ba ...
- Java源码详解六:ConcurrentHashMap源码分析--openjdk java 11源码
文章目录 注释 类的继承与实现 数据的存储 构造函数 哈希 put get 扩容 本系列是Java详解,专栏地址:Java源码分析 ConcurrentHashMap 官方文档:ConcurrentH ...
最新文章
- 一个基于SpringBoot + Mybatis + Vue的代码生成器
- 视觉SLAM前端特征检测与跟踪的思考
- 自定义函数_Access中的WorkDate自定义函数
- 专访浪潮王虹莉 探互联网服务器市场的未来
- 我转行成为机器学习和无人车工程师,并收获Offer
- Python中super()和__init__()方法
- [华为机试练习题]5.IP地址推断有效性
- typescript数组,对象,接口实例
- 【爬虫系列之一】爬虫开发环境的搭建
- 显示unc路径服务器根目录,错误:“您必须输入带有盘符的完整路径,例如:C:\ APPor形式的UNC路径:\\服务器\共享”...
- java 解决故意弄得错误,高效的Java错误处理
- Python 进程 Process 模块 - Python零基础入门教程
- linux命令音乐视频合并,Linux下基于命令行的音乐播放器 (1)
- 前端核心技术必备知识库精华资源强力推荐
- Hibernate课程 初探一对多映射3-3 单向多对一的测试
- ASP.NET Core 使用Redis 存储Session 实现共享 Session
- 拓端tecdat|R语言进行相关矩阵分析及其网络可视化
- Android签名方式
- 学生成绩管理信息系统
- 企业名录114_1.36
热门文章
- 用0到9十个数字,每个数字使用一次,构成两个五位数a和b,并且a+20295=b.求a,b
- LeetCode简单题之密钥格式化
- TensorFlow csv读取文件数据(代码实现)
- java爬取验证码图片_JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取)...
- ArrayAdapter requires the resource ID to be a TextView
- overridePendingTransition 方法在Fragment 中使用
- Android 双屏开发 Presentation 的使用教程
- AndroidManifest.xml
- Vue $createElement
- Oracl 12c (课本)