Proposal for 3.0 alignment with JSF 2.2: Scope management in support of 
@PreDestroy annotation
----------------------------------------------------------------------------------------------

                 Key: PORTLETBRIDGE-200
                 URL: https://issues.apache.org/jira/browse/PORTLETBRIDGE-200
             Project: MyFaces Portlet Bridge
          Issue Type: New Feature
          Components: General
    Affects Versions: 3.0.0
            Reporter: Neil Griffin
            Assignee: Michael Freedman


Section 6.8.1 of the Spec discusses the need for the @BridgePreDestroy 
annotation. Here's the background for the requirement...

Let's start by looking at the JavaDoc comments for the following methods on the 
JSF ExternalContext class: 
http://javaserverfaces.java.net/nonav/docs/2.0/javadocs/javax/faces/context/ExternalContext.html#getApplicationMap()
 
http://javaserverfaces.java.net/nonav/docs/2.0/javadocs/javax/faces/context/ExternalContext.html#getRequestMap()
 
http://javaserverfaces.java.net/nonav/docs/2.0/javadocs/javax/faces/context/ExternalContext.html#getSessionMap()
 

The design here seems good, in that it is servlet/portlet agnostic: The JSF API 
makes it clear that it is the responsibility of the underlying java.util.Map to 
invoke methods annotated with javax.annotation.PreDestroy when attributes are 
removed from the Map. 

But here is the problem: The Mojarra and MyFaces JSF implementations don't have 
this logic in their Map implementations. Instead, they that they rely on the 
underlying Servlet Container (i.e. Tomcat) to call the listeners when 
attributes are added/removed. See: 
http://download.oracle.com/javaee/6/api/javax/servlet/ServletContextAttributeListener.html
 

Mojarra: The class named ConfigureListener implements the 
javax.servlet.ServletContextAttributeListener interface: 
http://java.net/projects/mojarra/sources/svn/content/trunk/jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java?rev=8946
 

MyFaces: The class named ManagedBeanDestroyerListener implements the 
javax.servlet.ServletContextAttributeListener interface: 
http://svn.apache.org/repos/asf/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/ManagedBeanDestroyerListener.java
 

To further explain the problem... Portlet Containers typically implement the 
javax.portlet.PortletRequest as a layer of abstraction on top of an underlying 
javax.servlet.http.HttpServletRequest. However, often times that underlying 
HttpServletRequest is issued against a webapp context other than that of the 
portlet. In the case of the typical Portal+Tomcat bundle, the browser issues an 
HTTP-GET request to the tomcat/webapps/ROOT context. If the JSF implementation 
(Mojarra or MyFaces) where present in the tomcat/webapps/ROOT context, then 
their ServletContextAttributeListeners would get invoked. But that's not where 
the JSF implementation typically lives -- instead, it lives in a different 
context like tomcat/webapps/my-jsf-portlet. So that means in a (local) portal 
environment, the ServletContextAttributeListeners do not get invoked. 

What's further complicates things... There are two different kinds of portals: 
Local (like Liferay) and Remote (like Oracle WebCenter). Local Portals invoke 
portlets that are running within the same servlet container. Remote Portals 
invoke portlets that are running elsewhere via WSRP. As I stated earlier, in 
the case of Local Portals, the Mojarra and MyFaces 
ServletContextAttributeListeners don't get invoked in other contexts. BUT in 
the Remote Portal WSRP scenario, the Mojarra and MyFaces 
ServletContextAttributeListeners DO INDEED get invoked. 

Finally, the last component of the problem is that the JSF API doesn't really 
address the whole idea of scope management, such as listening to when a scope 
comes to an end. That's left as an implementation detail, and the bridge 
basically is left in the dark as to when underlying map entries are supposed to 
go out-of-scope, and also has no idea which entries in the map are managed 
beans, unless they are annotated with the @ManagedBean annotation. 

So that's why Section 6.8.1 introduces the @BridgePreDestroy annotation. In a 
portlet environment, Mojarra/MyFaces cannot be relied upon to invoke methods 
annotated with plain old @PreDestroy. They might, or they might not. So in 
order to have a reliable mechanism for a "pre destroy" type of annotated method 
in a portlet environment, the Bridge provides the @BridgePreDestroy annotation. 
It is guaranteed to always work in a portlet environment. 

So this issue serves as a proposal to align with the JSF 2.2 EG in order to 
fortify the JSF API with scope management (or scope listening) features. This 
would also enable us to deprecate the @BridgePreDestroy feature. Bear in mind 
that CDI comes into play here as well. Whatever we do, we want to play nicely 
with CDI when it is present in the portlet application.


--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to