-
1. Re: How to share Spring application context across multiple WARs in AS7
swoeste Sep 14, 2011 3:29 AM (in response to billhong)Hi Bill,
we have nearly the same problem here. Actually I am trying to port our application from AS4 (also successfully running with AS5) to AS7.
The behavior is nearly the same as you already described. Our Spring Context is initialized during the deployment and will be shared with all WARs within this EAR application.
Our Structure:
Application.ear
|-X.war
|-Y.war
|-EJB.jar
The deployment finish successfully but if I try to access the registered web context, then I get the following exception:
java.lang.IllegalStateException: Context attribute is not of type WebApplicationContext: Root WebApplicationContext: startup date [Wed Sep 14 08:43:22 CEST 2011]; parent: ApplicationContext 'four-tier'
org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext(WebApplicationContextUtils.java:124)
org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext(WebApplicationContextUtils.java:99)
de.zeb.control.fw.pl.presentationutils.filter.InitializingSpringContextFilter.doFilterInternal(InitializingSpringContextFilter.java:45)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:83)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
de.zeb.control.fw.pl.presentationutils.filter.IE6Kb843518Filter.doFilter(IE6Kb843518Filter.java:76)org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
de.zeb.control.fw.pl.presentationutils.filter.GZIPCompressionFilter.doFilter(GZIPCompressionFilter.java:66)
The Code that throws the exception is the following:
public static WebApplicationContext getWebApplicationContext(ServletContext sc, String attrName) {
Assert.notNull(sc, "ServletContext must not be null");
Object attr = sc.getAttribute(attrName);
if (attr == null) {
return null;
}
if (attr instanceof RuntimeException) {
throw (RuntimeException) attr;
}
if (attr instanceof Error) {
throw (Error) attr;
}
if (attr instanceof Exception) {
throw new IllegalStateException((Exception) attr);
}
if (!(attr instanceof WebApplicationContext)) {
throw new IllegalStateException("Context attribute is not of type WebApplicationContext: " + attr);
}
return (WebApplicationContext) attr;
}
While I was debugging that code I have discovered that attr is a XMLWebApplicationContext which implements the WebApplicationContext interface. So it seems that there is a problem with the classloader …
Have you already solved your problem or does any one has a solution for this kind of problem?
Thanks
Sebastian
-
2. Re: How to share Spring application context across multiple WARs in AS7
billhong Sep 14, 2011 5:03 AM (in response to swoeste)Sebastian,
The class loader would be fine as long as all shared JAR packages are put in /lib folder of the EAR package. The trick here is AS7.0 loads WARs, SARs in the same EAR package by multiple threads. You won't know which component will be initialized first when doing deployment. Therefore, I gave up the way to load Spring Context in mbean service since there's no way to guarantee SAR is loaded first.
Here is the way I solve this problem in my environment:
1) Create a listener which is used to load spring context and put it in web.xml for all WARs.
<listener>
<listener-class>com.xxx.SpringContextLoader</listener-class>
</listener>2) Create synchronized method and only allows the first thread call this method to load spring context. Other threads will need to wait until Spring Context is loaded.
I still do not find a similar way in JBoss which acts like Weblogic's ApplicationLifecycleListener. Please let me know if you work out a better solution.
-Bill