【发布时间】:2020-01-17 12:21:32
【问题描述】:
我正在升级一个在 Java6 + Spring 3.2.2 + Jersey 1.19 + Tomcat6 上正常工作的旧 Web 应用程序,以便使用每个组件的更新版本(Java8 + Spring 5.1.5 + Jersey 2.28 + Tomcat9),但是当我尝试启动它时出现问题。该应用在Tomcat启动过程中失败,特别是在Spring ApplicationContext的初始化过程中,我收到了以下消息:
INFO: Initializing Spring root WebApplicationContext
org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization started
org.springframework.context.support.AbstractApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myBean': Invocation of init method failed; nested exception is java.lang.NullPointerException
org.springframework.web.context.ContextLoader initWebApplicationContext
SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myBean': Invocation of init method failed; nested exception is java.lang.NullPointerException
....
Caused by:
at my.package.utils.AppAssets.getContext()
出现错误的部分代码如下:
public static ApplicationContext getContext() {
if (ctx == null) {
ctx = ApplicationContextProvider.getApplicationContext();
}
return ctx;
}
特别是,ApplicationContextProvider 是一个在应用程序中获取 ApplicationContext 的有用类,如下所示:
package my.package.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext ctx = null;
public static ApplicationContext getApplicationContext() {
return ctx;
}
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
this.ctx = ctx;
}
}
applicationContext.xml 是:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="applicationContextProvider" class="my.package.utils.ApplicationContextProvider">
</bean>
<bean id="Resources" class="my.package.resources.Resources">
<property name="iniFile" value="/WEB-INF/properties/config.properties">
</property>
</bean>
</beans>
我的 web.xml 配置是:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>MYWEBAPP</display-name>
<!-- PATH SERVER - CONFIGURATION -->
<context-param>
<param-name>realPathName</param-name>
<param-value>rootPath</param-value>
</context-param>
<!-- LOG4J - CONFIGURATION -->
<context-param>
<param-name>log4j-config-location</param-name>
<param-value>WEB-INF/properties/log4j.properties</param-value>
</context-param>
<!-- LISTENER CONTEXT CONFIGURATION -->
<listener>
<listener-class>my.package.context.ContextListener</listener-class>
</listener>
<!-- SPRING - CONFIGURATION -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- JERSEY - CONFIGURATION - FILTER FOR SPRING AND JSPs -->
<filter>
<filter-name>jersey</filter-name>
<filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>my.package.rest</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.mvc.templateBasePath.jsp</param-name>
<param-value>/WEB-INF/pages</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.server.mvc.jsp.JspMvcFeature</param-value>
</init-param>
<init-param>
<param-name>jersey.config.servlet.filter.staticContentRegex</param-name>
<param-value>/(images|js|styles|resources|(WEB-INF/pages))/.*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jersey</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
如果有用的话,我还附上previous web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID"
version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>MYWEBAPP</display-name>
<!-- PATH SERVER - CONFIGURATION -->
<context-param>
<param-name>realPathName</param-name>
<param-value>rootPath</param-value>
</context-param>
<!-- LOG4J - CONFIGURATION -->
<context-param>
<param-name>log4j-config-location</param-name>
<param-value>WEB-INF/properties/log4j.properties</param-value>
</context-param>
<!-- LISTENER CONTEXT CONFIGURATION -->
<listener>
<listener-class>my.package.context.ContextListener</listener-class>
</listener>
<!-- RESTFUL WEB APPLICATION -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- JERSEY - FILTER FOR SPRING AND JSPs -->
<filter>
<filter-name>jersey</filter-name>
<filter-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</filter-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>my.package.rest</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
<param-value>/WEB-INF/pages</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
<param-value>/(images|js|styles|resources|(WEB-INF/pages))/.*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jersey</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
最后,Spring 似乎未能初始化 ApplicationContext,因为 util 类的 getter 返回 null 但我不明白为什么:使用旧版本成功初始化了上下文,这要归功于 ApplicationContextAware 功能。我的怀疑是 Spring 和 Jersey 之间的交互配置错误,这会阻止 ApplicationContextAware 正常工作。我做错了什么?
感谢您的帮助
【问题讨论】:
-
您一次完成了很多事情。一次做一件事并采取小步骤。不要立即从 Spring 3.x 转到 5.x,采取中间步骤。请记住,您有一个正在运行的应用程序,每个小的更改都应该导致一个正在运行/工作的应用程序。一次性完成所有这些操作不会让您知道究竟是什么东西出了问题。
标签: java spring web.xml tomcat9