springboot在jetty+websocket的环境下的junit测试失败

kuma_ller 发布于 2018/05/27 14:28
阅读 783
收藏 0

这个问题描述起来可能还比较长。

首先我在springboot中选择了jetty作为服务器,然后现在我希望使用jetty的websocket功能,因此边加了jetty的websocket包。按照网上的教程,只要注意把tomcat的包剔除掉,再加上springboot的websocket包就可以生效了。但实际上并没有生效,我通过gradle的依赖分析找到了原因,是因为jetty的websocket包和tomcat的冲突了。

虽然前面已经exclude掉了tomcat的包,那只是剔除了主体,而tomcat.embed包(内含tomcat的websocket)依赖存在的,因为这个包剔除比较麻烦,于是我直接在configurations那里把所有tomcat.embed的都exclude掉了。

configurations {
   	all*.exclude group: 'org.apache.tomcat.embed'
}

于是jetty的websocket就生效了,问题暂时解决。

但是后来我使用junit4去测试的时候报错(但是真正运行是正常的),异常链是Fail to load ApplicationContext,我找到最底层的报错,原因是因为ServletContext中找不到一个叫DecoratedObjectFactory的ObjectFactory。

我通过断点对比了一下正式运行时和Junit运行时ServletContext有什么不同,发现这两种方式下的ServletContext其实是不一样的对象:

↑这是junit测试时的ServletContext对象

↑这是正常运行jetty时的ServletContext对象

在JettyEmbeddedWebAppContext中是可以找到DecoratedObjectFactory的,但是junit下的SpringBootMockServletContext是找不到的。

获取DecoratedObjectFactory的代码在org.eclipse.jetty.websocket.server.WebSocketServerFactory下的doStart()中:

if(this.objectFactory == null && context != null)
        {
            this.objectFactory = (DecoratedObjectFactory) context.getAttribute(DecoratedObjectFactory.ATTR);
            if (this.objectFactory == null)
            {
                throw new IllegalStateException("Unable to find required ServletContext attribute: " + DecoratedObjectFactory.ATTR);
            }
        }

从junit下的SpringBootMockServletContext这个名称中可以看到这是一个springboot为测试环境Mock的对象,我现在初步怀疑是sprintboot对jetty的websocket支持还不完善,也就是说这是一个bug。

请各位指教。

加载中
返回顶部
顶部