异常描述
我的开发环境如下
框架:springboot,mybatis ……
工具:eclipse
数据库:MySQL
在开发工程中,使用启动类启动能够正常启动并测试。问题出在,我将项目打成war包,整个项目不能启动。
我在打包的时候做了如下操作:1
1.修改启动类
将启动类继承了SpringBootServletInitializer
,并且重写了configure
方法。
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
// 注意这里要指向原先用main方法执行的Application启动类
return builder.sources(Application.class);
}
2.修改依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 移除嵌入式tomcat插件 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加servlet-api的依赖 -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>8.0.36</version>
<scope>provided</scope>
</dependency>
3.修改打包方式
<packaging>war</packaging>
4.maven-install打包
打包完成后,在tomcat-8.0.46中执行,出现以下错误提示
13-Sep-2017 09:49:34.794 严重 [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal One or more Filters failed to start. Full details will be found in the appropriate container log file
13-Sep-2017 09:49:34.799 严重 [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal Context [/cloudwifi] startup failed due to previous errors
[localhost-startStop-1] INFO o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext - Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1fb1bdfc: startup date [Wed Sep 13 09:49:21 CST 2017]; root of context hierarchy
[localhost-startStop-1] INFO o.s.j.e.a.AnnotationMBeanExporter - Unregistering JMX-exposed beans on shutdown
[localhost-startStop-1] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
13-Sep-2017 09:49:34.857 警告 [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [cloudwifi] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
13-Sep-2017 09:49:34.860 警告 [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [cloudwifi] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
然后在localhost.log日志中出现如下错误提示
13-Sep-2017 09:49:19.318 信息 [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log 2 Spring WebApplicationInitializers detected on classpath
13-Sep-2017 09:49:25.494 信息 [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log Initializing Spring embedded WebApplicationContext
13-Sep-2017 09:49:34.793 严重 [localhost-startStop-1] org.apache.catalina.core.StandardContext.filterStart Exception starting filter com.some.filter.Filter003
javax.naming.NamingException: Cannot create resource instance
at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:96)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at org.apache.naming.NamingContext.lookup(NamingContext.java:847)
at org.apache.naming.NamingContext.lookup(NamingContext.java:172)
at org.apache.catalina.core.DefaultInstanceManager.lookupFieldResource(DefaultInstanceManager.java:550)
at org.apache.catalina.core.DefaultInstanceManager.processAnnotations(DefaultInstanceManager.java:452)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:142)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:119)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:258)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4700)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5340)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:753)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:729)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1129)
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1871)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
13-Sep-2017 09:49:34.794 严重 [localhost-startStop-1] org.apache.catalina.core.StandardContext.filterStart Exception starting filter com.some.filter.Filter002
javax.naming.NamingException: Cannot create resource instance
at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:96)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at org.apache.naming.NamingContext.lookup(NamingContext.java:847)
at org.apache.naming.NamingContext.lookup(NamingContext.java:172)
at org.apache.catalina.core.DefaultInstanceManager.lookupFieldResource(DefaultInstanceManager.java:550)
at org.apache.catalina.core.DefaultInstanceManager.processAnnotations(DefaultInstanceManager.java:452)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:142)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:119)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:258)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4700)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5340)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:753)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:729)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1129)
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1871)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
13-Sep-2017 09:49:34.807 信息 [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
以上是出现错误的详细过程
- 1 ↩
异常定位
注意tomcat启动时,在控制台中的一段异常信息
那么,就是说tomcat在加载Filter的时候出现了错误。检查我的Filter,我发现了如下依赖
这里对具体的类做了隐藏,但是SomeObject有如下特点
1.他是一个Spring的依赖
2.他的具体值是依赖于数据库
问题1
排除问题的时候一直觉得应该是启动顺序的问题,但是自己还是不是特别确定。先回顾一下加载顺序
listener-->filter-->sevlet-->spring
因为我的filter依赖了spring中的对象,所以其实在加载过程中filter会出现filter的加载异常
问题2
使用了
@Resource
注解,这个注解是javax标准的,其实不仅spring会使用它,甚至连tomcat也会使用它。所以tomcat在启动过程中才会去尝试加载资源someone。又因为someone其实依赖了数据库的,所以才会出现javax.naming.NamingException: Cannot create resource instance
这个异常。解决办法
使用其他方式添加Filter
首先Filter不再使用
@WebFilter
注解,新增@Component
注解,将这个类变成Spring的组件,推迟他的加载不使用
@Resource
注解因为tomcat也会识别
@Resource
,所以我们不再使用它,改为使用@Autowired
和@Qualifier
这两个注解。使用Spring的方式添加Filter
这里就随便贴一个教程吧
http://blog.csdn.net/mzh1992/...