Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: Release 1.5.1
-
Fix Version/s: Release 1.5.4, Release 1.6
-
Component/s: ActionBean Dispatching
-
Labels:None
-
Environment:WebSphere Application Server 6.1.0.0, JDK 1.5, Servlet 2.4
Description
DynamicMappingFilter fails with message:
Could not get a reference to StripesFilter from the servlet context. The dynamic mapping filter works in conjunction with StripesFilter and requires that it be defined in web.xml
even though StripesFilter is defined in web.xml.
Problem lies in following statement in JavaDoc documentation of the filter:
- {@link StripesFilter} and {@link DispatcherServlet} need not be mapped to any URL patterns in
- {@code web.xml} since this filter will determine at runtime whether or not they need to be
- invoked.
This is like I have had it:
<filter>
<display-name>Stripes Filter</display-name>
<filter-name>StripesFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
... proper init params
</filter>
<filter>
<filter-name>DynamicMappingFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.DynamicMappingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>DynamicMappingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
Which is correct according to documentation and works for example on Tomcat.
Problem is that StripesFilter init method needs to be called - it writes a specific attribute into the ServletContext that is expected by DynamicMappingFilter (naturaly - because it means StripesFilter has been initialized). But this method is not called on WAS while having this configuration.
I found out that WAS applies different lifecycle on the filters (I wonder whether it doesn't violate the Servlet specification?). It doesn't call init methods of filters and servlets on web application start, but delays it up to the time when Filters are really needed (means if there is request to the url the filter participates in). And when no filter-mapping for the StripesFilter is defined - it is never called although its definition is present in web.xml.
Solution that works for me is simple - just adding filter mapping for Stripes filter:
<filter-mapping>
<filter-name>DynamicMappingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
And StripesFilter is initialized at last.
From servlet spec 2.4:
===
SRV.6.2.1 Filter Lifecycle
After deployment of the Web application, and before a request causes the container
to access a Web resource, the container must locate the list of filters that must be
applied to the Web resource as described below. The container must ensure that it
has instantiated a filter of the appropriate class for each filter in the list, and called its
init(FilterConfig config) method...
===
The behavior you describe seems to be legitimate based on that excerpt. I'll see what I can do about working with it.
Mapping StripesFilter to /* is exactly what I was trying to avoid when I chose not to extend StripesFilter to create DynamicMappingFilter. StripesFilter isn't terribly heavyweight, but it's more than you want to do for every single request for an image, stylesheet, javascript file, etc.