8 Replies Latest reply on Sep 22, 2006 6:44 PM by gavin.king

    Using Seam for porlet communication

      Hello,
      I'd like to use Seam to help JSR-168 portlets to communicate between each others (e.g. portlet1.jsp, portlet2.jsp). My first very naive approach (using Statefull Session Beans) didn't seem to work. Maybe it didn't work because somebody (JSF,Seam?) sees the two portlets as two different "clients", so different SFSBs are created for two different portlets.

      Portlet1.jsp uses action1 (SFSB) to get a list of organizations, action2 is different SFSB.

      action1.java

      @DataModel
      List organizations;
      


      portlet1.jsp
      <h:dataTable value="#{organizations}" var="org">
       <h:commandLink value="#{org.name}" action="#{action2.getEventsForOrg}">
       <f:param name="organizationId" value="#{org.organizationId}" />
       </h:commandLink>



      action2.java
      @RequestParameter("organizationId")
      private String organizationId;
      
      @DataModel(value = "orgEvents")
      List orgEvents;
      


      portlet2.jsp
      <h:dataTable value="#{orgEvents}" var="event">
       <h:column>
       <f:facet name="header">
       <h:outputText value="Type" />
       </f:facet>
       <h:outputText value="#{event.type}" />
       </h:column>
      </h:dataTable>
      



      pages.xml
      <pages>
       <page view-id="/portlet2.jsp" action="#{action2.getEventsForOrg}" />
      </pages>
      



      However, it seems that two different instances of action2 are created, one for the portlet1.jsp (action="#{action2.getEventsForOrg}" and other one for portlet2.jsp accesses. It doesn't matter if i use the pages.xml above or call action2 inside the portlet2.jsp.

      Is this Seam abuse ;) or misconfiguration?





        • 1. Re: Using Seam for portlet communication

          According to http://wiki.java.net/bin/view/Portlet/JSR168FAQ " How do I achieve inter-portlet communication ?" one can use the Application Scope for intra portlet communication.

          If in action2.java i change the scope to APPLICATION it works as "expected".

          @Stateful
          @Name("action2")
          @Scope(ScopeType.APPLICATION)
          


          But does this mean that the action2 and it's state is now shared with all the users? If so changing the scope to application is some kind of dissolution.

          This is what Seam docs say about the application scope: http://docs.jboss.com/seam/1.0.0.GA/reference/en/html/concepts.html#d0e2123

          Would it be possible to use the Business process context to transfer data between portlets? Or maybe add new context which is shared between portlets for one user. It's pretty weird that the Session context is not already shared between the portlets.


          • 2. Re: Using Seam for porlet communication

            Hmm. In org.jboss.seam.portlet.PortletSessionImpl.java it says

            public Object getAttribute(String key)
             {
             return session.getAttribute(key);
             }
            
            public void setAttribute(String key, Object value)
             {
             session.setAttribute(key, value);
             }
            
            

            which according to the Javadoc http://docs.jboss.org/jbportal/spec/docs/javax/portlet/PortletSession.html#getAttribute(java.lang.String) gets/puts the attributes in PORTLET_SCOPE which is defined to be portlet private only. And the APPLICATION_SCOPE is portal "wide" scope.

            Maybe in Seam we need new context APPLICATION_PORTLET_SCOPE (or PORTAL_SCOPE) that uses the Portlet APPLICATION_SCOPE for storage. ( http://docs.jboss.org/jbportal/spec/docs/javax/portlet/PortletSession.html#APPLICATION_SCOPE ). IMHO the portlet APPLICATION_SCOPE name is causing some naming conflits and should be renamed to PORTAL_SCOPE in the spec.

            Or just simply hard code and change the PortletSessionImpl to always use the (portlet) APPLICATION_SCOPE.



            • 3. Re: Using Seam for porlet communication

              This allows intra/inter portlet to portlet communication inside Seam. Basically everything that goes to Session scope is also put to both PORTLET_SCOPE(portlet private, only the portlet putting has access to it) and APPLICATION_SCOPE (portal wide, every portlet inside portal sees it). A more elegant/resource wise solution might be better, but it is not actually trivial without adding new configuration options.

              /*
               * JBoss, Home of Professional Open Source
               *
               * Distributable under LGPL license.
               * See terms of license at gnu.org.
               */
              package org.jboss.seam.portlet;
              
              import java.util.Collections;
              import java.util.Enumeration;
              import java.util.List;
              
              import javax.portlet.PortletSession;
              
              import org.apache.commons.collections.ListUtils;
              import org.jboss.seam.contexts.ContextAdaptor;
              
              /**
               * @author <a href="mailto:theute@jboss.org">Thomas Heute </a>
               * @version $Revision: 1.4 $
               */
              public class PortletSessionImpl extends ContextAdaptor {
              
               private PortletSession session;
              
               public PortletSessionImpl(PortletSession session) {
               this.session = session;
               }
              
               public Object getAttribute(String key) {
               // search for key first in PORTLET_SCOPE
               Object o = session.getAttribute(key);
               Object po = null;
               // if nothing is found there try APPLICATION_SCOPE
               if (o == null) {
               po = session.getAttribute(key, PortletSession.APPLICATION_SCOPE);
               return po;
               } else {
               // TODO: just do some cleaning up or maybe not
               // session.removeAttribute(key, PortletSession.APPLICATION_SCOPE);
               }
              
               return o;
               }
              
               public void removeAttribute(String key) {
               session.removeAttribute(key);
               session.removeAttribute(key, PortletSession.APPLICATION_SCOPE);
               }
              
               public Enumeration getAttributeNames() {
               Enumeration portletAttributeNamesEnum = session.getAttributeNames();
               Enumeration portalAttributeNamesEnum = session
               .getAttributeNames(PortletSession.APPLICATION_SCOPE);
              
               List portletAttributeNames = Collections
               .list(portletAttributeNamesEnum);
               List portalAttributeNames = Collections.list(portalAttributeNamesEnum);
              
               // TODO: Is this correct?
               List allNames = ListUtils.sum(portalAttributeNames,
               portalAttributeNames);
              
               return Collections.enumeration(allNames);
               }
              
               public void setAttribute(String key, Object value) {
               session.setAttribute(key, value);
               session.setAttribute(key, value, PortletSession.APPLICATION_SCOPE);
               }
              
               public void invalidate() {
               session.invalidate();
               }
              
              }
              


              • 4. Re: Using Seam for porlet communication
                • 5. Re: Using Seam for porlet communication
                  • 6. Re: Using Seam for porlet communication
                    mzeijen

                    I am also very interresting in this topic. I was looking at you implementation of the PortletSessionImpl and I noticed that you simple put the attribute in both the portlet SESSION_SCOPE and the portlet APPLICATION_SCOPE. Isn't that very dangerous because you can have collissions between portlets?

                    • 7. Re: Using Seam for porlet communication

                      Yes, it can be dangerous but as i said this is the very naive approach ;)

                      However, i'm currently (once again) trying to get Facelets work in Seam+Portlet and i'm getting these nice exceptions:

                      This could help me with the exception i'm currently facing:



                      java.lang.ClassCastException: com.liferay.portlet.RenderResponseImpl
                      at com.sun.facelets.FaceletViewHandler.createResponseWriter(FaceletViewHandler.java:371)
                      at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:557)
                      at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:384)
                      at org.apache.myfaces.portlet.MyFacesGenericPortlet.nonFacesRequest(MyFacesGenericPortlet.java:322)
                      at org.apache.myfaces.portlet.MyFacesGenericPortlet.nonFacesRequest(MyFacesGenericPortlet.java:297)
                      at org.apache.myfaces.portlet.MyFacesGenericPortlet.facesRender(MyFacesGenericPortlet.java:379)
                      at org.apache.myfaces.portlet.MyFacesGenericPortlet.doView(MyFacesGenericPortlet.java:265)
                      at javax.portlet.GenericPortlet.doDispatch(GenericPortlet.java:235)
                      at javax.portlet.GenericPortlet.render(GenericPortlet.java:163)
                      at com.liferay.portal.kernel.servlet.PortletServlet.service(PortletServlet.java:89)
                      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                      at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
                      at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:574)
                      at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:499)
                      at com.liferay.portlet.CachePortlet._invoke(CachePortlet.java:295)
                      at com.liferay.portlet.CachePortlet.render(CachePortlet.java:155)
                      at org.apache.jsp.html.portal.render_005fportlet_jsp._jspService(render_005fportlet_jsp.java:708)
                      at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
                      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                      at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
                      at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
                      at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
                      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                      at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
                      at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:574)
                      at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:499)
                      at com.liferay.portal.util.PortalUtil.renderPortlet(PortalUtil.java:948)
                      at com.liferay.portlet.layoutconfiguration.util.RuntimePortletUtil.processPortlet(RuntimePortletUtil.java:123)
                      at com.liferay.portlet.layoutconfiguration.util.velocity.PortletColumnLogic.processContent(PortletColumnLogic.java:76)
                      at com.liferay.portlet.layoutconfiguration.util.velocity.TemplateProcessor.processColumn(TemplateProcessor.java:58)
                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                      at java.lang.reflect.Method.invoke(Method.java:585)
                      at org.apache.velocity.util.introspection.UberspectImpl$VelMethodImpl.invoke(UberspectImpl.java:267)
                      at org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:197)
                      at org.apache.velocity.runtime.parser.node.ASTReference.execute(ASTReference.java:175)
                      at org.apache.velocity.runtime.parser.node.ASTReference.render(ASTReference.java:220)
                      at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:230)
                      at org.apache.velocity.app.Velocity.evaluate(Velocity.java:316)
                      at org.apache.velocity.app.Velocity.evaluate(Velocity.java:210)
                      at com.liferay.portlet.layoutconfiguration.util.RuntimePortletUtil.processTemplate(RuntimePortletUtil.java:165)
                      at com.liferay.portlet.layoutconfiguration.util.RuntimePortletUtil.processTemplate(RuntimePortletUtil.java:146)
                      at org.apache.jsp.html.portal.layout.view.portlet_jsp._jspService(portlet_jsp.java:414)
                      at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
                      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                      at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
                      at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
                      at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
                      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                      at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
                      at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:574)
                      at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:499)
                      at com.liferay.taglib.util.IncludeTag.doEndTag(IncludeTag.java:63)
                      at org.apache.jsp.html.portal.layout_jsp._jspService(layout_jsp.java:417)
                      at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
                      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                      at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
                      at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
                      at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
                      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                      at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
                      at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:574)
                      at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:499)
                      at com.liferay.taglib.util.IncludeTag.doEndTag(IncludeTag.java:63)
                      at org.apache.jsp.html.themes.classic.templates.portal_005fnormal_jsp._jspService(portal_005fnormal_jsp.java:1024)
                      at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
                      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                      at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
                      at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
                      at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
                      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                      at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
                      at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:574)
                      at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:499)
                      at com.liferay.taglib.util.ThemeUtil.includeJSP(ThemeUtil.java:139)
                      at com.liferay.taglib.util.ThemeUtil.include(ThemeUtil.java:93)
                      at com.liferay.taglib.util.IncludeTag.doEndTag(IncludeTag.java:58)
                      at org.apache.jsp.html.common.themes.portal_jsp._jspx_meth_liferay$1theme_include_1(portal_jsp.java:555)
                      at org.apache.jsp.html.common.themes.portal_jsp._jspx_meth_c_otherwise_0(portal_jsp.java:527)
                      at org.apache.jsp.html.common.themes.portal_jsp._jspService(portal_jsp.java:433)
                      at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
                      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                      at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
                      at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
                      at org.apache.jasper.servlet.JspServlet.service(J


                      • 8. Re: Using Seam for porlet communication
                        gavin.king

                        I'm also interested in this topic, so keep the suggestions coming .... though I don't expect to be able to do much work on it for a couple of months.