MyFaces Core
  1. MyFaces Core
  2. MYFACES-3375

MyFaces can incorrectly determine that Portlets are not supported

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.9
    • Fix Version/s: 2.0.10, 2.1.4
    • Component/s: JSR-314, Portlet_Support
    • Labels:
      None

      Description

      There are two issues I'd like to report here.

      1) Bridge Class is specific to Apache

      org.apache.myfaces.shared.util.ExternalContextUtils.java / isPortlet(ExternalContext ec) does the following:

      return getRequestType(ec).isPortlet();

      This class. contains the logic to determine if Portlet is supported by finding a Bridge class and can return the incorrect value when a Bridge other than the Apache Bridge is available. For instance in
      WebSphere Application Server (WAS) when running in a Portlet environment the MyFaces code incorrectly returns a Servlet RequestType.

      After looking at the code I see why this is:
      //Summary of values obtained
      javax.portlet.PortletContext = _PORTLET_CONTEXT_CLASS
      javax.portlet.ActionRequest = _PORTLET_ACTION_REQUEST_CLASS
      javax.portlet.RenderRequest = PORTLET_RENDER_REQUEST_CLASS
      javax.portlet.ResourceRequest = _PORTLET_RESOURCE_REQUEST_CLASS

      //Find bridge to tell if portal is supported
      Class<?> bridge = ClassLoaderUtils.loadClass("javax.portlet.faces.Bridge");

      If the above javax.portlet.faces.Bridge Class is not found then PortletSupported variables are set to false. There needs to be a better way to determine if a Bridge is
      available and therefore determine if Portlets are supported in this environment.

      2) Portlet support is determined globally which is not always the case, a more granular determination is needed at the application level.

        Activity

        Paul Nicolucci created issue -
        Hide
        Leonardo Uribe added a comment -

        After checking the code it seems it is not really necessary to check for javax.portlet.faces.Bridge, which causes the problem here. I changed the code in this way:

        //Find bridge to tell if portal is supported
        if(context != null)
        {
        // Portlet 1.0 API found. In this case we have to consider that exists alternate
        // bridge implementations like in WebSphere and others.
        portlet10Supported = true;

        try
        {
        Class<?> bridge = ClassLoaderUtils.loadClass("javax.portlet.faces.Bridge");

        if(bridge != null)
        {
        //Standard bridge defines a spec name which can be used to
        //determine Portlet 2.0 Support.
        String specName = bridge.getPackage().getSpecificationTitle();
        _LOG.fine("Found Bridge: " + specName);
        if(specName != null && specName.startsWith("Portlet 2"))

        { portlet20Supported = true; }

        if(_LOG.isLoggable(Level.INFO))

        { String ver = (portlet20Supported)?"2.0":"1.0"; _LOG.info("Portlet Environment Detected: " + ver); }

        }
        }
        catch (ClassNotFoundException e)
        {
        _LOG.fine("Portlet API is present but Standard Apache Portlet Bridge is not. " +
        " This could happen if you are using an alternate Portlet Bridge solution.");

        if (resourceRequest != null)

        { portlet20Supported = true; }

        }
        }

        To allow alternate portlet bridge implementations not following the standard to work. I'll close this issue as fixed, but please reopen it again if this does not work in your case, explaining the reasons about it.

        Show
        Leonardo Uribe added a comment - After checking the code it seems it is not really necessary to check for javax.portlet.faces.Bridge, which causes the problem here. I changed the code in this way: //Find bridge to tell if portal is supported if(context != null) { // Portlet 1.0 API found. In this case we have to consider that exists alternate // bridge implementations like in WebSphere and others. portlet10Supported = true; try { Class<?> bridge = ClassLoaderUtils.loadClass("javax.portlet.faces.Bridge"); if(bridge != null) { //Standard bridge defines a spec name which can be used to //determine Portlet 2.0 Support. String specName = bridge.getPackage().getSpecificationTitle(); _LOG.fine("Found Bridge: " + specName); if(specName != null && specName.startsWith("Portlet 2")) { portlet20Supported = true; } if(_LOG.isLoggable(Level.INFO)) { String ver = (portlet20Supported)?"2.0":"1.0"; _LOG.info("Portlet Environment Detected: " + ver); } } } catch (ClassNotFoundException e) { _LOG.fine("Portlet API is present but Standard Apache Portlet Bridge is not. " + " This could happen if you are using an alternate Portlet Bridge solution."); if (resourceRequest != null) { portlet20Supported = true; } } } To allow alternate portlet bridge implementations not following the standard to work. I'll close this issue as fixed, but please reopen it again if this does not work in your case, explaining the reasons about it.
        Leonardo Uribe made changes -
        Field Original Value New Value
        Status Open [ 1 ] Resolved [ 5 ]
        Assignee Leonardo Uribe [ lu4242 ]
        Fix Version/s 2.0.10 [ 12317870 ]
        Fix Version/s 2.1.4 [ 12317868 ]
        Resolution Fixed [ 1 ]
        Leonardo Uribe made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Transition Time In Source Status Execution Times Last Executer Last Execution Date
        Open Open Resolved Resolved
        9d 4h 26m 1 Leonardo Uribe 04/Nov/11 19:13
        Resolved Resolved Closed Closed
        11d 6h 9m 1 Leonardo Uribe 16/Nov/11 01:22

          People

          • Assignee:
            Leonardo Uribe
            Reporter:
            Paul Nicolucci
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development