Attached is the current draft of chapter 8 on the JSR 301 spec (portlet bridge).  It describes things developers of Faces extensions should be aware of to cohabitate with a bridge/run in a portlet environment.

The short answer to your question is no, the bridge won't help you here.  Portlet 1.0 didn't define support for filters or wrapping request/response objects.  Hence initialization done in filters in the servlet environment should be rewritten/migrated to FacesContextFactory.
     -Mike-

Rashmi wrote:
Hallo,

       can myfaces portlet bridge can be used in someway to overcome the
porblem?

Regards,
Rashmi 


Scott O'Bryan wrote:
  
Ok.  I'll need to add a few utilities to the common utilities and add a 
common configurator jar to the project.  But it should be easy enough to 
do in my copious amounts of free time.  I'm currently in the middle of 
restructuring the bridge projects (which is almost done as well) so let 
me get that done and I'll check in the configurators so people can take 
a look at possibly using them.

Scott

Matthias Wessendorf wrote:
    
Another option is I've been tinkering with separating the configurator
system similar to what Trinidad uses in order to put into an Apache
commons project.  The code is complete (albeit untested) but the
configurators are a way to duplicate *most* filter logic in a JSF
environment without the use of filters.  It works for both portlet and
servlet environements. If you want me to try and get that checked in to
the commons, maybe Orchestra can use it?
    
        
yeah, I think that others may benefit from the Trinidad configurator
"framework"
as well. I think that Orchestra definitely is a valid use case for that.
Looks like (from what I remember on old discussions) Tobago also has
interest
in that.

-M

  
      
Scott


Simon Kitching wrote:
    
        
BTW, you might try adding these elements to the OrchestraServletFilter
filter-mapping clause:

      <dispatcher>REQUEST</dispatcher>
      <dispatcher>FORWARD</dispatcher>
      <dispatcher>INCLUDE</dispatcher>

Regards,
Simon

---- Simon Kitching <[EMAIL PROTECTED]> schrieb:

      
          
Hi Rashmi,

Again, exact line numbers from the latest snapshot would be useful.

In an email you sent to me directly you said that with the latest
snapshot the exception was at line 83 of ConversationManager. But with
the latest code, that line is in the middle of a javadoc comment, so
perhaps you got the libraries mixed up?

The latest snapshot is always here:
 
http://people.apache.org/repo/m2-snapshot-repository/org/apache/myfaces/orchestra/myfaces-orchestra-core/1.1-SNAPSHOT/

As the comments in JsfFrameworkAdapter say:
  This class requires the JsfFrameworkAdapterFilter to
  be configured to run on every JSF request.

And JsfFrameworkAdapterFilter says:
 Note that the conversation.jsf.OrchestraServletFilter
 class executes this class as a "subfilter", so defining
 this filter is not required if that filter is already defined.

So as long as you have OrchestraServletFilter defined there is no need
to configure anything else. And I certainly hope you have the
OrchestraServletFilter defined; that is mandatory.

As someone mentioned earlier that filters run at unusual times during
portlet processing, that might be the cause of the problem. Neither
Mario nor I use portlets so you'll need to look into that yourself
although we are both happy to help with advice.

I think that getting Orchestra and portlets working together will not
be too difficult; it looks like is just the initialisation of basic
structures that is not happening in a portlet environment.

But getting the correct line at which the NullPointerException is
actually happening would be a very good start...

Regards,
Simon

---- Rashmi <[EMAIL PROTECTED]> schrieb:

        
            
Hallo Mario,

       We tried using the latest snapshot of Orchestra. Unfortunately
still
facing the same exception as
       before.

       After having tried debugging the application, I see that it
fails in
class SpringConversationScope -
       protected Object getBean(String beanName, ObjectFactory
objectFactory) {...} method. It displays
       the conversation name correctly, but fails in next step:

      ConversationManager manager =
ConversationManager.getInstance();

      Is it possible through spring IOC I can try instantiating or
something?

      It clearly states in the Orchestra API, that the
BasicFrameworkAdapter
has been implemented for
      plain Servlet environment and JsfFrameworkAdapter for JSF
environment.

      In the configuration i.e web.xml I tried explicity setting the
filter
to JsfFrameworkAdapter but again
      failed.

      May be we will end up writing a portlet friendly adapter.
Please throw
some light on how to get
      started or any other workaround to overcome the problem.

Regards,
Rashmi


Mario Ivankovits wrote:

          
              
Hi!


            
                
currently we're prototyping a portlet application (liferay 4.33) 
with
orchestra , JPA (Hibernate) and myFaces 1.1.5.

              
                  
Unhappily I have zero experience with portlets. If you could provide
a
simple webapp to test this thing it would greatly help, though, I
know
how much work it is to setup one.
However, if possible somehow, please try the latest snapshot of
Orchestra as we've changed how the FrameworkAdapter will be
initialized.
At least it gives us correct line numbers in the exception.

The FrameworkAdapter brings me to the thing which might be needed to
be
fixed for the portlet environment, not sure though.

If you have a look at the source of this class you'll see that there
are
just a handful of methods which needs to be implement, probably in a
portlet friendly way.

Could you please check if you have access to a FacesContext close
before
the method raising an exception?

If so, you can stick with the JsfFrameworkAdapter and just need to
find
a way how to initialize it properly. If not, you have to create your
own
portlet friendly FrameworkAdapter wich allows you to get access to
the
session/request stuff required by Orchestra.


Ciao,
Mario

            
                
      
          
    
        

  
      

    

  
Title: Chapter 8: Faces Extensions in the Bridge Environment

8


Faces Extensions in the Bridge Environment

It is common for Faces applications to run in an extended Faces environment.  I.e. one where the applications relies on function not provided in the base (reference) implementation but rather is provided by an implementation using one of the many extensions mechanisms Faces defines.  As the portlet bridge also is in part built as a Faces extension consideration needs to be given by these other Faces extension developers to ensure proper execution in a portlet environment..  

8.1 Configuration

Because its the bridge's implementation that abstracts the details of running in a portlet environment its important that the bridge extensions execute as close as possible to the base layer as possible.  This is why the bridge's FacesContextFactory is configured as a service provider.  To run correctly all other application extensions that aren't defined in the application's faces-config.xml should be configured in the META-INF/faces-config.xml in their jar file.  They should not be registered as a service provider.

Unfortunately, the Faces extensions implemented by the bridge aren't limited to those that are configured via the service provider mechanism.  The bridge also extends the ViewHandler and StateManager[6.2 and 6.3].  The ViewHandler and StateManager are configured in its faces-config.xml that its in the META-INF directory of its jar file.  As Faces doesn't define a set precedence order when like configuration exists in other faces-config.xml files that are also in a jar's META-INF directory, one can't control or determine whether or where in the ViewHandler or StateManager chains the bridge's implementation will be called.  To avoid obscuring other extensions, the bridge delegates where ever possible and then augments the result. When this is not feasible, the bridge ensures it at least duplicates the behavior defined by the RI for this function.  Other extensions are expected to be implemented in a similar manner to avoid obscuring necessary bridge behavior.  I.e. they either delegate to ensure the bridge gets a chance to execute or they implement  the bridge's function directly. Sections 8.5 and 8.6 discusses this in detail.

8.2 Initializing Extensions

If an extension subsystem needs to perform one time intialization, it is recommended it rely on providing a ServletContext listener as defined in the Servlet specification.

If an extension subsystem needs to perform per request initialization, it is recommended it provide its own implementation of FacesContextFactory and perform this initialization in the appropriate activation calling sequence.

Commonly such initialization involves wrapping either the request or response objects to support extended semantics on these objects.  In the Servlet environment extensions have two options, they can wrap the request or response object before delegating the creation of the FacesContext/ExternalContext or they can wrap later and replace the request/response object managed by the ExternalContext using the setRequest or setResponse calls.  Because the portlet API doesn't directly support such wrapping, extensions must only use the later mechanism when wrapping a portlet request or response.  I.e. so that the bridge can properly dispatch Faces requests it must be constructed with the original portlet request and response objects.

Some Faces extensions use servlet filters to manage they per request initializations/processing.  Because filters aren't supported in the portlet environment, this will not work.  Instead its recommended the extension use the "provide a FacesContextFactory" technique discussed in this section.  

8.3 Portlet Considerations

There may be times when an extension needs to determine if its running in a portlet vs. a servlet environment.  Generally the check needs to be made without regard to whether the bridge and/or portlet container are actually deployed in the environment.  The simpliest technique relying on instanceof javax.servlet.ServletRequest(Response) is insufficient because some portlet containers may have extended the underlying servlet request/response object in implementing PortletRequest/PortletResponse.  Instead the extension should look for the existence of the bridge's request attribute which holds the current portlet phase. The attribute name is javax.portlet.faces.portletPhase. If this attribute exists it is a portlet request.

boolean isPortletRequest =
    externalContext.getRequestMap().containsKey("
javax.portlet.faces.portletPhase");

When the bridge can be assumed to be deployed in the application, the utility method javax.portlet.faces.BridgeUtil.isPortletRequest() may be used instead.

8.4 General Considerations

Extensions should:
  1. avoid interacting directly with container specific objects.  Instead rely on the ExternalContext abstraction.
  2. when interacting directly with container specific objects, provide support for both the Servlet and Portlet containers.
  3. avoid completely overridding any method.  Where its necessary to do so, the extension must provide equivalent function as specified in this specification. 

8.5 Cohabitating with the Bridge's ViewHandler

Because of limitations in the Faces configuration environment there is no way to order extensions that are defined (exclusively) in the faces-config.xml. This applies to the Faces ViewHandler.  This means when running in an environment where other subsystems also introduce a ViewHandler, one can't predict whether the bridge's ViewHandler will take precedence or not. The bridge is designed to cohabitate with these other ViewHandlers regardless of the actual precedence order.  However the same may not be true of these other ViewHandlers. To work correctly in a portlet environment with the bridge, other ViewHandler extensions are expected to:
  • Not run any (servlet) non-portlet container specific code when executing a portlet request.
  • If the extension's ViewHandler.createView() returns its own UIViewRoot whose Class.getName isn't javax.faces.component.UIViewRoot then the extension should have its UIViewRoot implement the same semantics for portlet namespacing as described in section 6.6.  I.e. the implementation class of its UIViewRoot should be annotated to indicate it implements the portlet namespacing semantics and also provide such an implementation.
  • If the extension's ViewHandler.renderView() handles its own form of rendering then the extension should ensure the same style of response interleaving as provided by the default renderView and the bridge.

8.6 Cohabitating with the Bridge's StateManager

Because of limitations in the Faces configuration environment there is no way to order extensions that are defined (exclusively) in the faces-config.xml. This applies to the Faces StateManager.  This means when running in an environment where other subsystems also introduce a StateManager one can't predict whether the bridge's StateManager will take precedence or not. The bridge is designed to cohabitate with these other StateManagers regardless of the actual precedence order.  However the same may not be true of these other StateManagers. To work correctly in a portlet environment with the bridge, other StateManager extensions are expected to:
  • Not generate any output directly within the writeState(FacesContext context, Object state). I.e. the extension should rely/override other methods that are called when writeState is executed to generate any output.  If this is not feasible, the extension developer should document the issue to inform portlet application developers that when using the extension in a bridge environment they need to move the StateManager configuration from the bridge jar's faces-config.xml and put it into the applications (WEB-INF) faces-config.xml.  This ensures the bridge's StateManager runs before the extensions and hence isn't obscured by it.
  • Delegate writeState(FacesContext context, Object state) to the next StateManager in the chain.  Note:  a common practice when implementing a StateManager (in earlier Faces versions) was to extend javax.faces.application.StateManager and to delegate calls to this super class.  To work properly with the bridge such implementations need to change to delegate to the next StateManager in the chain.  This is most easily done by reimplementing the StateManager as an extension of javax.faces.application.StateManagerWrapper.

8.7 Excluding Attributes

When executing an extension may store temporary state in the request scope.  Because the bridge extends the life of this scope, extensions should explicitly exclude those attributes which do not need to be preserved.  I.e. are recreated as needed in each (portlet) request.  The preferred way to exclude such an attribute is to annotate the class of the attribute's value with  javax.portlet.faces.annotation.ExcludeFromManagedRequestScope.  If this is not feasible, attributes can be excluded by declaring them in the extension jar's faces-config.xml as described in 5.1.2.1.   When using this technique care should be taken to only exclude attributes that are uniquely namespaced as other portlets in the same web application may rely on other extensions and/or attributes that might collide with a non-unique name and be mistakenly excluded.  In such a situation when non-uniquely namespaced attributes are used, the extension developer should merely document for the portlet developer her need to configure such an exclusion in the application's portlet.xml for each portlet that utilizes the extension.


Reply via email to