Affects Version/s: bridge-api-3.0.0, bridge-api-4.0.0, bridge-impl-3.1.0, bridge-impl-4.1.0
Section 4.1 of the JSR 301/329 Specification titled "Configuration" states:
... the GenericFacesPortlet reads the following portlet initialization parameters and either sets the appropriate context attributes to direct the bridge's execution or uses it to impact its own behavior:
* indicates a parameter that affects bridge execution
** indicates a parameter that only affects GenericFacesPortlet execution
In addition, Section 4.2 of the Specification titled "Structure" states:
The GenericFacesPortlet subclasses javax.portlet.GenericPortlet. It overrides the init, destroy, doDispatch, doEdit, doHelp, doView, processAction, and renderHeaders methods. In addition it defines the following new methods:
* indicates a method that corresponds to one of the aforementioned parameters that affect bridge execution
Because of these requirements, WEB-INF/portlet.xml init-param values (stored in PortletConfig) are saved/cached as namespaced PortletContext attributes (not PortletContext parameters) with the following naming format:
There are benefits and drawbacks to these requirements:
- The "javax.portlet.faces" (standards based) init-param values listed in Section 4.1 are read and processed once at initialization time, providing a potential performance enhancement, however some of these could instead be done in the Bridge.init(PortletConfig) implementation.
- The developer can @Override methods listed in Section 4.2 in order to change default behavior, but is probably very very rarely used since most JSF portlets are able to use GenericFacesPortlet without subclassing it.
- Each time the EG wants to add a new "javax.portlet.faces" (standards based) init-param feature, it involves:
- Adding a new constant to Bridge.java
- Adding a corresponding method to GenericFacesPortlet.java
- Ensuring that GenericFacesPortlet.java calls the corresponding method and caches the value as a namespaced PortletContext attribute.
- The JSR 378 BridgePortletConfigFactory (see ---
---) is unable to decorate these init-param values, because GenericFacesPortlet.init(PortletConfig) cannot assume that the portlet container implementation will complete sending servlet context initialization events prior to calling Portlet.init(PortletConfig). In terms of the Mojarra implementation of JSF, GenericFacesPortlet cannot assume that the Mojarra ConfigureListener will execute and fire javax.faces.event.PostConstructApplicationEvent before the portlet is initialized. The result is that GenericFacesPortlet cannot assume that any of the bridge's factories (such as the BridgePortletConfigFactory) have been initialized by scanning META-INF/faces-config.xml descriptors for factory extensions. FACES-2685
- The getBridgeEventHandler() and getBridgePublicRenderParameterHandler() methods utilize Java's Thread Context Class Loader (TCCL) in the API jar module, which can cause classpath problems an an OSGi environment, or an application server that deploys API jars as OSGi modules.
- In order for getBridgeEventHandler() to utilize the BridgeEventHandlerFactory and getBridgePublicRenderParameterHandler() to utilize the BridgePublicRenderParameterHandlerFactory (see FACES-2778) the API has to create an instance of a BridgeEventHandler / BridgePublicRenderParameterHandler that defers actual factory lookup until the first request, but utilizing a thread-safe double-check idom.
This issue serves as a proposal for:
1. Deprecating the following constants in javax.portlet.faces.Bridge:
2. Deprecating the corresponding methods in javax.portlet.faces.GenericFacesPortlet:
3. Preventing GenericFacesPortlet.init(PortletConfig) from calling the methods listed in #2, which would in turn prevent the following PortletContext attributes from being set at initialization time:
4. Introducing the following constant in GenericFacesPortlet.java, which is a portlet initialization parameter (default is false) that when set to true in portlet.xml, would cause GenericFacesPortlet.init(PortletConfig) to work as designed in JSR 301/329.
5. Handling this functionality in the implementation, following the basic principle that less code in the API is more desirable than more code in the API.
This issue is closely related to
FACES-3098 which, if standardized would cause ExternalContext.getInitParameter(String) and ExternalContext.getInitParameterMap() first check PortletConfig.getInitParameter(String) before calling PortletContext.getInitParameter(String).