You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Wes Wannemacher <we...@wantii.com> on 2010/04/26 15:37:49 UTC

Re: Question about interceptor/action strategy... is this a major bug?

Christian, according to this page -

http://struts.apache.org/2.x/docs/writing-interceptors.html

Interceptors must be thread-safe because they are not instantiated
per-request (like actions), but should be treated more like
singletons.

That being said, the behavior you describe almost surely appears to be
a bug. Knowing that interceptors need to be thread-safe, can you give
us a few more details (which application server you are using, which
JVM and which version of struts). Also, it would be interesting if we
could try to narrow this down to a unit test so that a fix can be
worked out and validated.

-Wes

On Mon, Apr 26, 2010 at 1:37 AM, Christian Stone <xt...@stonescape.net> wrote:
> I have been chasing down a bug for months where data is incorrectly posted, and I chased it down to what I believe is a major failing in the interceptor chain.
>
> From what I see through my blurry and tired eyes is that an interceptor list containing an instance of each interceptor is created for each action mapping.  When an action is called, each interceptor is called in turn.  All well in good... BUT...
>
> These methods are not synchronized.  The actionMapping for a given action holds on to an instance of each interceptor that it calls in turn for every request (the same instance)!  So for example, you have two requests coming in for the same action at the same time, and it requires both the ServletRequestAware and SessionAware functionality from ServletConfigInterceptor.
>        Request 1 enters the interceptor (assigning the context) and is assigned the request 1 ServletRequestAware information.
>        Request 2 enters the interceptor (assigning the context) and is assigned the request 2 ServletRequestAware information.
>        Request 1 speeds along and is now assigned the request 2 ServletRequestAware information.
>        Request 2 speeds along and is assigned the request 2 ServletRequestAware information.
>
> Now, I see the keyword final for the context, etc.. in this interceptor, and I honestly don't know if that makes the methods immune for multiple requests for synchronized items.  Presuming it does, great!  However, there are many (and I mean more than one or two) interceptors which don't make use of the final keyword, that are not synchronized, and set local variables based on the action/context that are mutable and can change during another call to the interceptor.
>        ParameterRemoverInterceptor...
>        PrepareInterceptor...
>        MethodFilterInterceptor...
>        ScopedModelDrivenInterceptor...
> etc. etc...
>
> I searched the documentation, and nowhere does it infer that interceptors were all prototypes, and from what I see they are functionally prototypes within an action.
>
> If I am correct here, there are several solutions.  However, I am noticing that Struts is currently failing under heavy loads where there are likely many requests to a main landing page at the same moment.  I have defined my own interceptors, and without knowing the true architecture, I captured the request in a class variable then dispatched the request onward to other components for additional processing... when I get control, I access the request again, and with the preResultListener method.  I noticed that the request magically changes in the ActionInvocation, and it wasn't until I noticed the object itself never changing that I first checked spring, and then the struts code for answers.
>
> So I have been contributing code, and I normally am pretty accurate with these things.  However, I would be very happy to hear that I am incorrect in these assertions :)
>
> Thanks in advance,
>
> Christian Stone
>
> (References)
> StrutsObjectFactory - creates the interceptor.
> InterceptorBuilder.constructInterceptorReference() - returns the list.
> DefaultConfiguration.buildFullActionConfig() - generates a list of instances for an action mapping.  This list is persistent for the lifecycle of the application!
> and XmlConfigurationProvider (same as DefaultConfiguration).
>
>
>
>
>
>



-- 
Wes Wannemacher

Head Engineer, WanTii, Inc.
Need Training? Struts, Spring, Maven, Tomcat...
Ask me for a quote!

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org