最近由于 jboot 升级了dubbo,导致很多用户无法使用 jboot 在 tomcat 正常运行,会报找不到类会出现如下的问题:
org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1333)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1167)
at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:520)
at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:501)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:120)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4660)
出现这个错误的原因并不是 jboot 去依赖或使用了spring的相关功能,而是由于在tomcat环境下,由于servlet 3.0 会去自动加载依赖所有 jar包的 web-fragment.xml。 这是 servlet 3.0 的标准。
从 dubbo 2.6.3 之后,dubbo.jar 内置了 web-fragment.xml
, web-fragment.xml
又去加载 org.springframework.web.context.ContextLoaderListener 进行 dubbo 内部的初始化过程,但是在 jboot 引入dubbo的时候,已经对spring 体系进行了排除,因此 tomcat 会出现如上的错误。
如何解决呢?
1、方案1、我已经向 dubbo 官方提出 issues 并给出解决方案 ,地址:https://github.com/apache/incubator-dubbo/issues/2570 ,这个需要等到官方的解决方案 或者 态度。
2、方案2、在自己的项目里,创建一个叫 org.springframework.web.context.ContextLoaderListener
实现接口 javax.servlet.ServletContextListener
, 不需要走任何的实现。例如:https://gitee.com/fuhai/jpress/blob/master/starter-tomcat/src/main/java/org/springframework/web/context/ContextLoaderListener.java 就不会再出现这样的错误。
3、方案3、若dubbo官方不解决这个问题,jboot可能考虑内置 org.springframework.web.context.ContextLoaderListener
这个类,做一个空的实现。