Uploaded image for project: 'Portals Bridges (Retired)'
  1. Portals Bridges (Retired)
  2. PB-108

JSF portlet bridge 1.0.0 implementation works incorrectly in a multi-user environment

Add voteWatch issue
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • None
    • None
    • jsf
    • None
    • MyFaces JSF 1.2 and Vignette Portal

    Description

      We have a Vignette / MyFaces 1.2 / portlet-bridge-1.0.0-beta based web application. When the development had started we've downloaded the latest version of the bridge at the time (roughly 08-2009) and still using this version.
      After we started testing in a multi-user environment it had become clear that the bridge periodically corrupts incoming action (but not render) portal requests. The corresponding buggy code and fixes are described below.

      1. Defective code
      The following 2 methods wrongly assume that temporary registration of the bridge instance as a phase listerner while executing a render request doesn't affect concurrent action request (s) execution through the same instance. In reality a concurrent action request can sneak in between the lifecycle.addPhaseListener(this) and lifecycle.removePhaseListener(this) calls and end prematuraly just after the RESTORE_VIEW JSF phase (because of the context.renderResponse() call).

      private void doFacesRender(
      RenderRequest request,
      RenderResponse response,
      FacesContext context,
      Lifecycle lifecycle,
      String scopeId,
      List <String> preExistingAttributes
      )
      throws BridgeException, BridgeUninitializedException, NullPointerException
      {
      ...
      if (context.getViewRoot() == null)
      {
      ...
      lifecycle.addPhaseListener(this);
      try

      { lifecycle.execute(context); }
      catch (Exception e)
      { ... }
      finally
      { lifecycle.removePhaseListener(this); }
      }
      ...
      }

      public void afterPhase(PhaseEvent event)
      {
      // only set renderresponse if in RESTORE_VIEW phase



      if (event.getPhaseId() == PhaseId.RESTORE_VIEW)
      { FacesContext context = event.getFacesContext(); // Now restore the Faces Messages restoreFacesMessageState(context); context.renderResponse(); }
      }

      2. Fixed code
      We've implemented and successfully tested the following fixes.

      private void doFacesRender(
      RenderRequest request,
      RenderResponse response,
      FacesContext context,
      Lifecycle lifecycle,
      String scopeId,
      List <String> preExistingAttributes
      )
      throws BridgeException, BridgeUninitializedException, NullPointerException
      {
      ...
      if (context.getViewRoot() == null)
      {
      ...
      //lifecycle.addPhaseListener(this);
      try
      { lifecycle.execute(context); }

      catch (Exception e)

      { ... }

      finally

      { //lifecycle.removePhaseListener(this); }

      ...
      }

      private synchronized Lifecycle getLifecycle()
      throws BridgeException
      {
      try
      {
      if (mLifecycle == null)
      {
      LifecycleFactory lifecycleFactory =
      (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
      String lifecycleId =
      mPortletConfig.getPortletContext().getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
      if (lifecycleId == null)

      { lifecycleId = LifecycleFactory.DEFAULT_LIFECYCLE; }

      mLifecycle = lifecycleFactory.getLifecycle(lifecycleId);
      mLifecycle.addPhaseListener(this);
      }
      return mLifecycle;
      }
      catch (FacesException e)

      { Throwable rootCause = e.getCause(); throw new BridgeException(e.getMessage(), rootCause); }

      }

      public void afterPhase(PhaseEvent event)
      {
      if (BridgeUtil.getPortletRequestPhase().toString().contains("ACTION_PHASE"))

      { return; }

      if (event.getPhaseId() == PhaseId.RESTORE_VIEW)

      { FacesContext context = event.getFacesContext(); // Now restore the Faces Messages restoreFacesMessageState(context); context.renderResponse(); }

      }

      Attachments

        Activity

          People

            Unassigned Unassigned
            lelkun Leonid Elkun

            Dates

              Created:
              Updated:

              Slack

                Issue deployment