Stripes

DynamicMappingFilter fails with "Could not get a reference to StripesFilter" on WAS 6.1

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major 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.

Activity

Hide
Ben Gunter added a comment - 09/Apr/09 11:07 AM

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.

Show
Ben Gunter added a comment - 09/Apr/09 11:07 AM 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.
Hide
Nick Stuart added a comment - 29/Oct/09 2:24 PM

This is happening in Glassfish v3 as well. V2 was working fine with out having a mapping value for StripesFilter.

Show
Nick Stuart added a comment - 29/Oct/09 2:24 PM This is happening in Glassfish v3 as well. V2 was working fine with out having a mapping value for StripesFilter.
Hide
david wade added a comment - 14/Nov/09 7:19 PM

It appears that WebSphere does indeed break the servlet spec but not as thought above. It may be relevant here so I will share.

The servlet spec states there will be only one instance of a particular named Filter, but we found if requests are already being received by WebSphere before/during the start of of a web application, WebSphere (6.1 FP13 thru FP27) will create multiple instances of the same named filter and initialize each one. However, come application shutdown, only the last instance has the destroy method invoked (because it loses the rest when the filters are put into presumably some map indexed by the filter name).

So, delaying Filter creation/initialization until the first request, while not against the servlet spec, is a bad idea because they really need to add synchronization code around the code responsible. Clearly they have not as multiple instances are created.

To reproduce, create a very simple web app with a Filter and one JSP. Put a constructor on the Filter that simply increments a static instance counter and outputs that instance number to stdout. Deploy, then stop the web app. Start up multiple clients requesting the JSP, then start the web app. When started, stop the clients and have a look at the SystemOut.log. Both machine the client is running on and the server need to be SMP machines to reliably demonstrate this issue.

Am happy to supply an example web app + source if nobody believes me that WebSphere could be so blatantly dumb. IBM currently in denial mode on this issue.

Show
david wade added a comment - 14/Nov/09 7:19 PM It appears that WebSphere does indeed break the servlet spec but not as thought above. It may be relevant here so I will share. The servlet spec states there will be only one instance of a particular named Filter, but we found if requests are already being received by WebSphere before/during the start of of a web application, WebSphere (6.1 FP13 thru FP27) will create multiple instances of the same named filter and initialize each one. However, come application shutdown, only the last instance has the destroy method invoked (because it loses the rest when the filters are put into presumably some map indexed by the filter name). So, delaying Filter creation/initialization until the first request, while not against the servlet spec, is a bad idea because they really need to add synchronization code around the code responsible. Clearly they have not as multiple instances are created. To reproduce, create a very simple web app with a Filter and one JSP. Put a constructor on the Filter that simply increments a static instance counter and outputs that instance number to stdout. Deploy, then stop the web app. Start up multiple clients requesting the JSP, then start the web app. When started, stop the clients and have a look at the SystemOut.log. Both machine the client is running on and the server need to be SMP machines to reliably demonstrate this issue. Am happy to supply an example web app + source if nobody believes me that WebSphere could be so blatantly dumb. IBM currently in denial mode on this issue.
Hide
david wade added a comment - 17/Nov/09 9:56 PM

IBM have agreed WebSphere is breaking the servlet spec and is working on patch for the multiple Filter instances issue. Will post an update once the fix is released.

Show
david wade added a comment - 17/Nov/09 9:56 PM IBM have agreed WebSphere is breaking the servlet spec and is working on patch for the multiple Filter instances issue. Will post an update once the fix is released.
Hide
Nikolaos added a comment - 10/May/10 4:16 PM

As Nicholas pointed out and I experienced yesterday... this too is also happening in GlassFish v3 Final.

So it clearly is at least a 2 app server container issue at this time... and most likely requires a cross container solution....

Show
Nikolaos added a comment - 10/May/10 4:16 PM As Nicholas pointed out and I experienced yesterday... this too is also happening in GlassFish v3 Final. So it clearly is at least a 2 app server container issue at this time... and most likely requires a cross container solution....
Hide
Ben Gunter added a comment - 18/May/10 9:29 AM

I just checked in a fix for this problem. DMF tries very hard to force the app server to initialize StripesFilter if it isn't available when needed. My hope is this will work for all containers, but I need some people to test it. I tested it in Glassfish 3. There's a new snapshot in the Sonatype snapshot repository with this fix.

Show
Ben Gunter added a comment - 18/May/10 9:29 AM I just checked in a fix for this problem. DMF tries very hard to force the app server to initialize StripesFilter if it isn't available when needed. My hope is this will work for all containers, but I need some people to test it. I tested it in Glassfish 3. There's a new snapshot in the Sonatype snapshot repository with this fix.
Hide
Russ Galloway added a comment - 29/Jun/10 2:28 PM

We've run into the same issue with WAS 6.1.0.19 and have tried the latest 1.5.4-snapshot without luck.

@Jan - Was the WAS build you got working version 6.1.0.0 specifically?

What does a complete web.xml look like with 1.5.4 working in WAS 6.1.x?

Show
Russ Galloway added a comment - 29/Jun/10 2:28 PM We've run into the same issue with WAS 6.1.0.19 and have tried the latest 1.5.4-snapshot without luck. @Jan - Was the WAS build you got working version 6.1.0.0 specifically? What does a complete web.xml look like with 1.5.4 working in WAS 6.1.x?
Hide
Nikolaos added a comment - 31/Aug/10 9:44 AM

Russ,

This is what I have in 1.5.3 that works for me in GlassFish v3.0.1 Final b22. If you want to run this in 1.5.4 Snapshot then simply omit the content between the "Begin workaround..." and "End workaround..." comments.

<filter>
<filter-name>StripesFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
<!-- Other init parameters - REMOVED for brevity -->
</filter>

<filter>
<filter-name>DynamicMappingFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.DynamicMappingFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>

<!--
TODO: TEMPORARY WORKAROUND for: http://www.stripesframework.org/jira/browse/STS-678
Begin Workaround DynamicMappingFilter for Stripes 1.5.3 and 1.6.0 but NOT 1.5.4
-->
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<!--
End Workaround DynamicMappingFilter
-->

<filter-mapping>
<filter-name>DynamicMappingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>

Show
Nikolaos added a comment - 31/Aug/10 9:44 AM Russ, This is what I have in 1.5.3 that works for me in GlassFish v3.0.1 Final b22. If you want to run this in 1.5.4 Snapshot then simply omit the content between the "Begin workaround..." and "End workaround..." comments. <filter> <filter-name>StripesFilter</filter-name> <filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class> <!-- Other init parameters - REMOVED for brevity --> </filter> <filter> <filter-name>DynamicMappingFilter</filter-name> <filter-class>net.sourceforge.stripes.controller.DynamicMappingFilter</filter-class> </filter> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping> <!-- TODO: TEMPORARY WORKAROUND for: http://www.stripesframework.org/jira/browse/STS-678 Begin Workaround DynamicMappingFilter for Stripes 1.5.3 and 1.6.0 but NOT 1.5.4 --> <filter-mapping> <filter-name>StripesFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping> <!-- End Workaround DynamicMappingFilter --> <filter-mapping> <filter-name>DynamicMappingFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
Hide
Nikolaos added a comment - 31/Aug/10 10:38 PM

The nice thing about 1.5.4 Snapshot is that it has a fix to DynamicMappingFilter for this issue. The problem unfortunately is that 1.5.4 Snapshot at this "current" time has serious issues when using nested Stripes Layout. So what I ended up doing is creating my own 1.5.3.1 Snapshot (for my purposes) that essentially is 1.5.3 w/ the changes to DynamicMappingFilter in 1.5.4.

If anyone is interested in this jar please let me know and I'll post it and its POM somewhere for people to download. Again this is not official... and includes no warranty of any kind... just a convenience for anyone that has this issue and wants to use 1.5.3.

BTW the other interesting thing w/ the new DynamicMappingFilter code is that it now allows for StripesFilter to not be explicitly defined in web.xml and the init-params essentially move from being in the StripesFilter definition to the DynamicMappingFilter definition. See below. BTW keeping things the old way works as well as under the covers a StripesFilter is instantiated.

ASIDE: In my quick testing it didn't appear that the trunk (1.6.x) had this fix but I could have been mistaken (though it is marked fixed for 1.6 in this ticket).

<!--
Don't need to explicitly define a StripesFilter anymore if you want to use DynamicMappingFilter in 1.5.4 Snapshot
<filter>
<filter-name>StripesFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
</filter>
-->
<filter>
<filter-name>DynamicMappingFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.DynamicMappingFilter</filter-class>
<init-param>
<param-name>ActionResolver.Packages</param-name>
<param-value>org.test.ui.web.action</param-value><!-- Automatically scans all sub-packages as well -->
</init-param>
<init-param>
<param-name>Interceptor.Classes</param-name>
<param-value>net.sourceforge.stripes.integration.spring.SpringInterceptor</param-value>
</init-param>
<init-param>
<param-name>Extension.Packages</param-name>
<param-value>
org.test.ui.stripes.extensions,
org.test.ui.stripes.reload.extension,
org.stripesstuff.stripersist,
net.sourceforge.stripes.integration.spring
</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>DynamicMappingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>

Show
Nikolaos added a comment - 31/Aug/10 10:38 PM The nice thing about 1.5.4 Snapshot is that it has a fix to DynamicMappingFilter for this issue. The problem unfortunately is that 1.5.4 Snapshot at this "current" time has serious issues when using nested Stripes Layout. So what I ended up doing is creating my own 1.5.3.1 Snapshot (for my purposes) that essentially is 1.5.3 w/ the changes to DynamicMappingFilter in 1.5.4. If anyone is interested in this jar please let me know and I'll post it and its POM somewhere for people to download. Again this is not official... and includes no warranty of any kind... just a convenience for anyone that has this issue and wants to use 1.5.3. BTW the other interesting thing w/ the new DynamicMappingFilter code is that it now allows for StripesFilter to not be explicitly defined in web.xml and the init-params essentially move from being in the StripesFilter definition to the DynamicMappingFilter definition. See below. BTW keeping things the old way works as well as under the covers a StripesFilter is instantiated. ASIDE: In my quick testing it didn't appear that the trunk (1.6.x) had this fix but I could have been mistaken (though it is marked fixed for 1.6 in this ticket). <!-- Don't need to explicitly define a StripesFilter anymore if you want to use DynamicMappingFilter in 1.5.4 Snapshot <filter> <filter-name>StripesFilter</filter-name> <filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class> </filter> --> <filter> <filter-name>DynamicMappingFilter</filter-name> <filter-class>net.sourceforge.stripes.controller.DynamicMappingFilter</filter-class> <init-param> <param-name>ActionResolver.Packages</param-name> <param-value>org.test.ui.web.action</param-value><!-- Automatically scans all sub-packages as well --> </init-param> <init-param> <param-name>Interceptor.Classes</param-name> <param-value>net.sourceforge.stripes.integration.spring.SpringInterceptor</param-value> </init-param> <init-param> <param-name>Extension.Packages</param-name> <param-value> org.test.ui.stripes.extensions, org.test.ui.stripes.reload.extension, org.stripesstuff.stripersist, net.sourceforge.stripes.integration.spring </param-value> </init-param> </filter> <filter-mapping> <filter-name>DynamicMappingFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
Hide
Nikolaos added a comment - 08/Nov/10 7:22 PM

Ben,

Shouldn't this ticket be marked resolved for 1.5.4?

ASIDE: Last time I had checked this wasn't resolved for 1.6.x; if its not then it shouldn't be marked fix there... No?

--Nikolaos

Show
Nikolaos added a comment - 08/Nov/10 7:22 PM Ben, Shouldn't this ticket be marked resolved for 1.5.4? ASIDE: Last time I had checked this wasn't resolved for 1.6.x; if its not then it shouldn't be marked fix there... No? --Nikolaos
Hide
David Gleeson added a comment - 09/Nov/10 1:54 PM

If this is actually resolved, 1.5.4 could be released which would be fantastic...

Show
David Gleeson added a comment - 09/Nov/10 1:54 PM If this is actually resolved, 1.5.4 could be released which would be fantastic...

People

Vote (4)
Watch (4)

Dates

  • Created:
    09/Apr/09 2:03 AM
    Updated:
    04/Jan/11 2:57 PM
    Resolved:
    09/Nov/10 10:33 PM