Reputation: 11
I'm upgrading an old web app that works properly on Java6 + Spring 3.2.2 + Jersey 1.19 + Tomcat6 in order to use more recent versions of each component (Java8 + Spring 5.1.5 + Jersey 2.28 + Tomcat9) but a problem arised when I tried to launch it. The app failed during Tomcat boot, in particular, during the initialization of the Spring ApplicationContext, I received the following message:
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()
The part of the code in which the error arised is the following:
public static ApplicationContext getContext() {
if (ctx == null) {
ctx = ApplicationContextProvider.getApplicationContext();
}
return ctx;
}
In particular, ApplicationContextProvider is an useful class to get ApplicationContext within the app, as follow:
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;
}
}
The applicationContext.xml is:
<?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>
My web.xml configurations are:
<?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>
If it can be useful, I also attach the previous web.xml configuration:
<?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>
At the end, it seems Spring failed to initialize the ApplicationContext because the getter of the util class return null
but I don't understand why: using old versions the context was successfully initialized, thanks to ApplicationContextAware features. My suspicion is that there is some wrong configuration for interactions between Spring and Jersey which prevents ApplicationContextAware from working properly. What am I doing wrong?
Thank for your help
Upvotes: 1
Views: 2308
Reputation: 11
I want to start by saying that the previous configuration already included the settings for scanning packages and using annotations (I only left out to report it in the snippets). So, I found a solution using @Component annotation on ApplicationContextProvider instead define it in applicationContext.xml
package my.package.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context = null;
public static ApplicationContext getApplicationContext() {
return context;
}
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
System.out.println("ApplicationContextProvider - SETTING SPRING CONTEXT!!!");
context = ctx;
System.out.println("ApplicationContextProvider - APP GOT SPRING CONTEXT!!!");
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="Resources" class="it.wmg.gambling.commons.base.resources.Resources">
<property name="iniFile" value="/WEB-INF/properties/config.properties">
</property>
</bean>
</beans>
Now the server starts up correctly and works, but I have not yet understood why this solution has solved the problem. Does anyone have an idea?
Upvotes: 0
Reputation: 257
Try changing beans properties as below:
Old Value
<?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">
New Value:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
Upvotes: 1
Reputation: 147
Have you tried making spring-beans-2.5.xsd as spring-beans.xsd.
As it is advised to use versionless.
Upvotes: 1