ICEfaces
  1. ICEfaces
  2. ICE-2936

Parser and digester implementations are not thread safe.

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7RC1
    • Fix Version/s: 1.7.1
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      ICEfaces + JSP tags

      Description

      There's a single instance of the D2DViewHandler in any ICEfacesApplication. This class uses an instance of com.icesoft.faces.webapp.parser.Parser to handle parsing JSP pages, which creates a UIComponentTree out of the tags using an instance of com.icesoft.faces.webapp.parser.JsfJspDigester

      It appears that the Digester is stateful from the nature of the methods used

      synchronized (this) {
                  digester.clear();
                  digester.push(rootTag);
                  digester.push(rootWire);
                  digester.parse(page);
              }


      The test I'm doing is to access the Timezone application, then using JMeter or the JavaClient create a new view with the Timezone application, interact, then dispose the View, repeat with up to 10 (or however many) views concurrently active.

      Disposing the view is an important step since freshly creating the view causes the page to be re-parsed, however having several users attempting to render the very first response simultaneously causes exceptions similar to the following:

      ---> Starting reparse at: 98509527659283 This one finishes second at 98509551246548 (A)
      ---> Starting reparse at: 98509527659435 This one never finishes!
      ---> Starting reparse at: 98509535873067 This one ends first at 98509550752061 (B)

      ERROR - Failed to execute JSP lifecycle. - com.icesoft.faces.webapp.parser.Parser
      java.lang.ClassCastException: com.icesoft.faces.application.D2DViewHandler$1
             at com.icesoft.faces.webapp.parser.XhtmlTag.setProperties(XhtmlTag.java:71)
             at javax.faces.webapp.UIComponentClassicTagBase.findComponent(UIComponentClassicTagBase.java:614)
             at javax.faces.webapp.UIComponentClassicTagBase.doStartTag(UIComponentClassicTagBase.java:1142)
             at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:200)
             at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:224)
             at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:224)
             at com.icesoft.faces.webapp.parser.Parser.parse(Parser.java:161)
             at com.icesoft.faces.application.D2DViewHandler.renderResponse(D2DViewHandler.java:516)
             at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:164)
             at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
             at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
             at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
             at com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:18)
             at com.icesoft.faces.webapp.http.core.PageServer$1.respond(PageServer.java:30)
             at com.icesoft.faces.webapp.http.servlet.ServletRequestResponse.respondWith(ServletRequestResponse.java:161)
             at com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet$ThreadBlockingRequestResponse.respondWith(ThreadBlockingAdaptingServlet.java:36)
             at com.icesoft.faces.webapp.http.core.PageServer.service(PageServer.java:40)
             at com.icesoft.faces.webapp.http.core.MultiViewServer.service(MultiViewServer.java:56)
             at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer$Matcher.serviceOnMatch(PathDispatcherServer.java:50)
             at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:19)
             at com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet.service(ThreadBlockingAdaptingServlet.java:19)
             at com.icesoft.faces.webapp.http.servlet.EnvironmentAdaptingServlet.service(EnvironmentAdaptingServlet.java:29)
             at com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet.service(MainSessionBoundServlet.java:106)
             at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:35)
             at com.icesoft.faces.webapp.http.servlet.PathDispatcher$Matcher.serviceOnMatch(PathDispatcher.java:52)
             at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:29)
             at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:79)
             at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
             at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:654)
             at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:445)
             at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)
             at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:292)
             at org.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:694)
             at org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:665)
             at org.apache.jsp.index_jsp._jspService(index_jsp.java:57)
             at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
             at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
             at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393)
             at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
             at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
             at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
             at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
             at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
             at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
             at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
             at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
             at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
             at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
             at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
             at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
             at java.lang.Thread.run(Thread.java:595)
      ---> Done parsing at: 98509550752061, took: 14878994 ns (B)
      ---> Done parsing at: 98509551246548, took: 23587265 ns (A)
      ---> Starting reparse at: 98509592642827 (C)
      1-Apr-2008 11:51:54 AM com.sun.faces.lifecycle.Phase doPhase
      SEVERE: JSF1054: (Phase ID: RENDER_RESPONSE 6, View ID: /timezone.jspx) Exception thrown during phase execution: javax.faces.event.PhaseEvent[source=com.sun.fac
      es.lifecycle.LifecycleImpl@6af790]
      ---> Done parsing at: 98509657462362, took: 64819535 ns (C)


      The exact exception varies from ClassCastExceptions to NullPointerExceptions and virtually anything in between.


      This wont be seen as a problem in our common test situations since it's difficult for a single user to nearly simultaneously access an application, and even JMeter has facilities to spread out the user generated load at test startup enough to avoid having re-entrantcy being encountered. But with RIM and other clients expecting View disposal to release resources this type of test scenario will be encountered more often.

        Activity

        Repository Revision Date User Message
        ICEsoft Public SVN Repository #17261 Wed Jul 30 13:55:32 MDT 2008 ted.goddard moved digester code into small synchronized block (ICE-2936)
        Files Changed
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/faces/webapp/parser/Parser.java
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #17260 Wed Jul 30 13:54:11 MDT 2008 ted.goddard moved digester code into small synchronized block (ICE-2936)
        Files Changed
        Commit graph MODIFY /icefaces/branches/icefaces-1.7/icefaces/core/src/com/icesoft/faces/webapp/parser/Parser.java
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #16755 Fri May 30 12:12:49 MDT 2008 greg.dick ICE-2936 synchronize to protect against reentrancy problems (continued)
        Files Changed
        Commit graph MODIFY /icefaces/branches/icefaces-1.7/icefaces/core/src/com/icesoft/faces/webapp/parser/Parser.java
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #16711 Tue May 27 10:10:10 MDT 2008 greg.dick ICE-2936 Synchronize the parse method as it's not threadsafe
        Files Changed
        Commit graph MODIFY /icefaces/branches/icefaces-1.7/icefaces/core/src/com/icesoft/faces/webapp/parser/Parser.java
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #16524 Mon Apr 28 10:49:14 MDT 2008 greg.dick ICE-2936 Synchronize the parse method because the digester is not thread safe. Later we can try caching the UIComponent tree per page
        Files Changed
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/faces/webapp/parser/Parser.java

          People

          • Assignee:
            Unassigned
            Reporter:
            Greg Dick
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: