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.




Reply via email to