You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Claudio Tasso <ta...@libero.it> on 2006/02/19 10:09:13 UTC
ExtensionsFilter does not seem to be THREAD SAFE
Hi,
using Tomahawk I experimented some problems with the ExtensionFilter, in
particular some errors occur when the MyFaces javascript is written
inside the body of the response.
This is the typical error message:
java.lang.StringIndexOutOfBoundsException
at java.lang.StringBuffer.insert(StringBuffer.java:905)
at
org.apache.myfaces.renderkit.html.util.DefaultAddResource.writeMyFacesJavascriptBeforeBodyEnd(DefaultAddResource.java:658)
at
org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter(ExtensionsFilter.java:138)
at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
Developer Preview
4].server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:699)
at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
Developer Preview
4].server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:397)
at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
Developer Preview
4].server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:833)
at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
Developer Preview
4].server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:430)
at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
Developer Preview
4].server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:216)
at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
Developer Preview
4].server.http.HttpRequestHandler.run(HttpRequestHandler.java:119)
at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
Developer Preview
4].server.http.HttpRequestHandler.run(HttpRequestHandler.java:112)
at
oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:215)
at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
Developer Preview
4].util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)
at java.lang.Thread.run(Thread.java:534)
This error occurs randomly. Looking at the AddResourceFactory code, I
see that only one AddResource instace exists and this instance is shared
among the servlet threads.
The ExtensionFilter calulates the beforeBodyEndPosition value (which is
a DefaultAddResource property) and then this value is used for writing
inside a StringBuffer which should contain the response body.
This is the code in ExtensionFilter the I'm talking about:
addResource.parseResponse(extendedRequest, extendedResponse.toString(),
servletResponse);
addResource.writeMyFacesJavascriptBeforeBodyEnd(extendedRequest,
servletResponse);
The problem is that a typical race condition seems to happen.
The beforeBodyEndPosition value is calulated for Thread1, which is
suspended. Then, Thread 2 starts and it modifies the
beforeBodyEndPosition value. When Thread2 terminates, Thread1 resumes
and it tries to write inside its body response at an index which is no
more valid.
The reason of this behaviour is (according to me) the following: there
is just one instance of DefaultAddResource, so the execution of
AddResource.parseResponse and
AddResource.writeMyFacesJavascriptBeforeBodyEnd should be atomic.
Please, let me know your opinions.
Re: ExtensionsFilter does not seem to be THREAD SAFE
Posted by Claudio Tasso <ta...@libero.it>.
Ok, I'm going to create a JIRA issue.
Martin Marinschek ha scritto:
>Yes, that is true.
>
>Bruno?
>
>regards,
>
>Martin
>
>On 2/19/06, Claudio Tasso <ta...@libero.it> wrote:
>
>
>>Hi,
>>using Tomahawk I experimented some problems with the ExtensionFilter, in
>>particular some errors occur when the MyFaces javascript is written
>>inside the body of the response.
>>This is the typical error message:
>>
>>java.lang.StringIndexOutOfBoundsException
>> at java.lang.StringBuffer.insert(StringBuffer.java:905)
>> at
>>org.apache.myfaces.renderkit.html.util.DefaultAddResource.writeMyFacesJavascriptBeforeBodyEnd(DefaultAddResource.java:658)
>> at
>>org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter(ExtensionsFilter.java:138)
>> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
>>Developer Preview
>>4].server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:699)
>> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
>>Developer Preview
>>4].server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:397)
>> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
>>Developer Preview
>>4].server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:833)
>> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
>>Developer Preview
>>4].server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:430)
>> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
>>Developer Preview
>>4].server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:216)
>> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
>>Developer Preview
>>4].server.http.HttpRequestHandler.run(HttpRequestHandler.java:119)
>> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
>>Developer Preview
>>4].server.http.HttpRequestHandler.run(HttpRequestHandler.java:112)
>> at
>>oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:215)
>> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
>>Developer Preview
>>4].util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)
>> at java.lang.Thread.run(Thread.java:534)
>>
>>This error occurs randomly. Looking at the AddResourceFactory code, I
>>see that only one AddResource instace exists and this instance is shared
>>among the servlet threads.
>>The ExtensionFilter calulates the beforeBodyEndPosition value (which is
>>a DefaultAddResource property) and then this value is used for writing
>>inside a StringBuffer which should contain the response body.
>>This is the code in ExtensionFilter the I'm talking about:
>>
>> addResource.parseResponse(extendedRequest, extendedResponse.toString(),
>> servletResponse);
>>
>>addResource.writeMyFacesJavascriptBeforeBodyEnd(extendedRequest,
>> servletResponse);
>>
>>
>>The problem is that a typical race condition seems to happen.
>>The beforeBodyEndPosition value is calulated for Thread1, which is
>>suspended. Then, Thread 2 starts and it modifies the
>>beforeBodyEndPosition value. When Thread2 terminates, Thread1 resumes
>>and it tries to write inside its body response at an index which is no
>>more valid.
>>
>>The reason of this behaviour is (according to me) the following: there
>>is just one instance of DefaultAddResource, so the execution of
>>AddResource.parseResponse and
>>AddResource.writeMyFacesJavascriptBeforeBodyEnd should be atomic.
>>
>>Please, let me know your opinions.
>>
>>
>>
>>
>>
>>
>>
>
>
>--
>
>http://www.irian.at
>
>Your JSF powerhouse -
>JSF Consulting, Development and
>Courses in English and German
>
>Professional Support for Apache MyFaces
>
>
>
Re: ExtensionsFilter does not seem to be THREAD SAFE (Again Urgent!!)
Posted by Martin Marinschek <ma...@gmail.com>.
+1
regards,
Martin
On 2/23/06, Mario Ivankovits <ma...@ops.co.at> wrote:
> Hi!
>
> Sorry for all my "urgent" mails, but I address them so only if I really
> think it IS urgent. ;-)
>
> > Yes, that is true.
> >
> This turned out to be a serious problem here.
>
> Not only the java.lang.StringIndexOutOfBoundsException problem, but also
> that it might deliver the content of another request in another session.
>
> This is due to the fact that the response buffer will be passed into
> DefaultAddResource which stores it in a member "originalResponse".
> At this moment it is possible that another request for the same context
> will pick up this content.
>
> And guess what, this is what we have here 3-5 times the day.
>
> Looking in DefaultAddResource makes me wonder why it has to be a context
> singleton?
> It is a rather lightweight class and it should be not that a performance
> loss if we simple instantiate it per request.
> Also we can get rid of the request attributes like HEADER_BEGIN_INFO....
> as then the whole class is request scoped.
>
> If it is due to the fact that it is hard to find the correct constructor
> I'll propose to add a setContextPath(String) to the AddResource interface.
> That way we can use the default constructor and simply set the context path.
>
> After "green light" from you I'll do it that way.
>
> Ciao,
> Mario
>
>
--
http://www.irian.at
Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German
Professional Support for Apache MyFaces
Re: ExtensionsFilter does not seem to be THREAD SAFE (Again Urgent!!)
Posted by Mario Ivankovits <ma...@ops.co.at>.
Hi!
Sorry for all my "urgent" mails, but I address them so only if I really
think it IS urgent. ;-)
> Yes, that is true.
>
This turned out to be a serious problem here.
Not only the java.lang.StringIndexOutOfBoundsException problem, but also
that it might deliver the content of another request in another session.
This is due to the fact that the response buffer will be passed into
DefaultAddResource which stores it in a member "originalResponse".
At this moment it is possible that another request for the same context
will pick up this content.
And guess what, this is what we have here 3-5 times the day.
Looking in DefaultAddResource makes me wonder why it has to be a context
singleton?
It is a rather lightweight class and it should be not that a performance
loss if we simple instantiate it per request.
Also we can get rid of the request attributes like HEADER_BEGIN_INFO....
as then the whole class is request scoped.
If it is due to the fact that it is hard to find the correct constructor
I'll propose to add a setContextPath(String) to the AddResource interface.
That way we can use the default constructor and simply set the context path.
After "green light" from you I'll do it that way.
Ciao,
Mario
Re: ExtensionsFilter does not seem to be THREAD SAFE
Posted by Martin Marinschek <ma...@gmail.com>.
Yes, that is true.
Bruno?
regards,
Martin
On 2/19/06, Claudio Tasso <ta...@libero.it> wrote:
> Hi,
> using Tomahawk I experimented some problems with the ExtensionFilter, in
> particular some errors occur when the MyFaces javascript is written
> inside the body of the response.
> This is the typical error message:
>
> java.lang.StringIndexOutOfBoundsException
> at java.lang.StringBuffer.insert(StringBuffer.java:905)
> at
> org.apache.myfaces.renderkit.html.util.DefaultAddResource.writeMyFacesJavascriptBeforeBodyEnd(DefaultAddResource.java:658)
> at
> org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter(ExtensionsFilter.java:138)
> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
> Developer Preview
> 4].server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:699)
> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
> Developer Preview
> 4].server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:397)
> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
> Developer Preview
> 4].server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:833)
> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
> Developer Preview
> 4].server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:430)
> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
> Developer Preview
> 4].server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:216)
> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
> Developer Preview
> 4].server.http.HttpRequestHandler.run(HttpRequestHandler.java:119)
> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
> Developer Preview
> 4].server.http.HttpRequestHandler.run(HttpRequestHandler.java:112)
> at
> oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:215)
> at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) -
> Developer Preview
> 4].util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)
> at java.lang.Thread.run(Thread.java:534)
>
> This error occurs randomly. Looking at the AddResourceFactory code, I
> see that only one AddResource instace exists and this instance is shared
> among the servlet threads.
> The ExtensionFilter calulates the beforeBodyEndPosition value (which is
> a DefaultAddResource property) and then this value is used for writing
> inside a StringBuffer which should contain the response body.
> This is the code in ExtensionFilter the I'm talking about:
>
> addResource.parseResponse(extendedRequest, extendedResponse.toString(),
> servletResponse);
>
> addResource.writeMyFacesJavascriptBeforeBodyEnd(extendedRequest,
> servletResponse);
>
>
> The problem is that a typical race condition seems to happen.
> The beforeBodyEndPosition value is calulated for Thread1, which is
> suspended. Then, Thread 2 starts and it modifies the
> beforeBodyEndPosition value. When Thread2 terminates, Thread1 resumes
> and it tries to write inside its body response at an index which is no
> more valid.
>
> The reason of this behaviour is (according to me) the following: there
> is just one instance of DefaultAddResource, so the execution of
> AddResource.parseResponse and
> AddResource.writeMyFacesJavascriptBeforeBodyEnd should be atomic.
>
> Please, let me know your opinions.
>
>
>
>
>
--
http://www.irian.at
Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German
Professional Support for Apache MyFaces