本地项目启动过程中报错如下:
07-Nov-2019 09:48:01.926 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.filterStart Exception starting filter ecFilter
com.baosight.iplat4j.core.exception.PlatException: E_Spring_BeansException
at com.baosight.iplat4j.core.spring.SpringApplicationContext.getBean(SpringApplicationContext.java:91)
at com.baosight.iplat4j.ec.util.UrlFilter.<init>(UrlFilter.java:32)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
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:4660)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5298)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1696)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:484)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:433)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at com.baosight.iplat4j.core.spring.SpringApplicationContext.getBean(SpringApplicationContext.java:88)
... 54 more
可以看到报了空指针错误,在SpringApplicationContext类中的getBean 方法中,代码如下:
getApplicationContext()方法返回null ,进入该方法:
public static ApplicationContext getApplicationContext() {
if(CONTEXT != null) {
return CONTEXT;
} else {
try {
lock.lock();
if(CONTEXT != null) {
ApplicationContext var0 = CONTEXT;
return var0;
}
System.out.println("[SpringApplicationContext] try init context...");
new ClassPathXmlApplicationContext("classpath*:spring/framework/applicationContext.xml");
new ClassPathXmlApplicationContext(fileNames);
if(CONTEXT == null) {
throw new Exception("[SpringApplicationContext] applicationContext未被初始化");
}
通过调试发现该方法的CONTEXT 属性为空,然后直接抛出了异常:application未被初始化。由于该类实现了applicationContextAware接口,因此在类初始化时applicationcontext 对象会赋给CONTEXT属性。
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
CONTEXT = applicationContext;
}
进一步调试发现,该set方法未执行,该类的构造方法也未执行,因此猜想是spring初始化类时出现了问题。所以接着调试web.xml中配置的spring容器初始化监听器ContextLoaderListener:
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = this.createContextLoader();
if(this.contextLoader == null) {
this.contextLoader = this;
}
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
直接看initWebApplicationContext方法
然后进入createWebApplicationContext 方法:
其中的refresh()方法描述了ApplicationContext的初始化过程,其中大部分操作都是执行Bean定义到BeanDefinition到Bean的过程。
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var4) {
this.destroyBeans();
this.cancelRefresh(var4);
throw var4;
}
}
}
refresh 方法中的obtainFreshBeanFactory方法只要执行了xml配置的bean的定义搜集操作:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if(this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
再看其中的refreshBeanFactory方法:
protected final void refreshBeanFactory() throws BeansException {
if(this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
beanFactory.setSerializationId(this.getId());
this.customizeBeanFactory(beanFactory);
this.loadBeanDefinitions(beanFactory);
Object var2 = this.beanFactoryMonitor;
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var4) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var4);
}
}
可以看到其中的loadBeanDefinitions方法就是去加载xml配置的bean定义的过程:
顺着这个方法往下找,最终可以找到加载contextConfigLocation中配置的xml文件加载路径的方法:
由于项目中配置了bean定义xml文件在spring/ 路径下,而此处加载路径时 返回的resourcesUrls为空。所以没有初始化bean。
后来发现是由于 项目结构中的 artifacts配置有问题,编译输出的class文件没放到web-inf classes 文件夹下,导致找不到xml配置文件。
修改output layout 后重新编译问题就解决了