I recently started working on a JSR-168 portlet project and, as a fresh graduate, am still quite new to Java EE in general and JSF/Portlets in particular. I went through quite some trouble to get RichFaces to work in my portlets. And although not everything is working yet, I thought I would just write down my experiences so that other users might have a starting point. There is a lot of information about portlet support in the forum, jira and the wiki, but almost nothing of that seemed to be what I was looking for. Maybe other people can add their experiences or correct me when I'm wrong, maybe we can even turn this into a portlet tutorial or something like that.
Like probably everybody else too, I started by deploying the portal-echo demo portlet supplied in the repository using JBoss Portal 2.6.1 on top of JBoss 4.2.0.GA. That however, soon came to an end. At first, the MyFaces-libs were missing. After adding them (and telling JBoss about it via web.xml), the lib containing the org.ajax4jsf.portlet packaged was missing so I added this one as well. After I had done this, I had conflicts with all those common-libs (logging in particular), so I removed them from the war. That didn't help either as the digester now had a hickup when trying to initialize MyFaces. That's the point were I just gave up.
Lucky for me, I wasn't the only one having troubles. So I finally stumbled across a working demo-portlet provided by Michael Karas aka suckerd while helping some other user. http://jira.jboss.com/jira/secure/attachment/12316176/portlet-jsfrichfacesdemo.war
That was the first RichFaces portlet I could deploy. And as simple as it was, I was quite happy to finally see that blue gradient of the blueSky skin in a locally portlet. The libs required to run the portlet seem to be richfaces-api-x.x.x.jar, richfaces-impl-x.x.x.jar, richfaces-ui-x.x.x.jar (distributed e.g. in the binary downloads of richfaces), portlet-x.x.x.jar (nedds to be built first, can be found in the extensions/portlet dir in the project source code) and jsf-facelets-portal.jar. To get it to work on JBP 2.6.2, I also had to add the (latest) commons-beanutils-1.8.0-BETA, commons-collections-3.2 and commons-digester-1.8 libs.
I stripped down the config of that portlet (especially all the xml-files except for the ones really needed, that is faces-config.xml, portlet.xml and web.xml), and with the instructions given in section 3.3 of the RichFaces user guide, I managed to do my own little portal-echo portlet.
After all that success, I started to change my existing portlets from using Sun's JSF portlet bridge in conjunction with plain JSF/JSP to using the org.ajax4jsf.portlet.AjaxFacesPortlet in conjunction with Facelets/xhtml.
I encountered some quirks there too, though:
First off, the AjaxFacesPortlet does not seem to support EDIT and HELP mode out of the box. As far as I understand, I need to override the doHelp and doEdit methods to achieve that, but didn't have time to figure out where these init-params are processed.
Also, I had to place my pages directly in the root of the portlet. Storing them in WEB-INF/jsf didn't work, ended up in a 404 error whenever some ajax-magic happened.
The mediaOutput component doesn't seem to work either. It always throws a FacesException (AJAX call to portlet without namespace parameter).
Another component I tried to use was the a4j:include which didn't seem to work either.
Oh, and it seems like one could only use one skin at a time. Different RichFaces skin-configurations in different portlets on the same page seem to be overridden by the last portlet's skin.
Did anybody get these components to work? Is there a list of components working in a portlet? The wiki says all richfaces components do work in portlets. How about the a4j-part?
I really like RichFaces and A4J and am willing to help making it more stable. Keep up the good work.
I used the following environment for my tests:
- Java SE Development Environment 1.6.0_03-b05
- JBoss Portal 2.6.2 on top of JBoss AS 4.2.1 with pre-installed JSF Sun-RI 1.2_04
- RichFaces 3.1.2.CR2, RichFaces Portlet Extension 3.1.2.CR2
- Sun JSF Portlet Bridge 1.2.1 with this https://jsfportletbridge.dev.java.net/issues/show_bug.cgi?id=20, SUN JSF Facelets 1.1.14
- Commons Beanutils 1.7.0, Commons Collections 3.2, Commons Digester 1.8
I had to apply the patch to the Sun JSF Portlet Bridge because I ran into the problem mentioned in http://jira.jboss.org/jira/browse/RF-572:
19:12:28,377 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception java.lang.ClassCastException: org.apache.catalina.core.ApplicationContextFacade cannot be cast to javax.portlet.PortletContext at com.sun.faces.portlet.FacesContextFactoryImpl.getFacesContext(FacesContextFactoryImpl.java:64) at org.ajax4jsf.resource.InternetResourceService.getFacesContext(InternetResourceService.java:317) at org.ajax4jsf.resource.InternetResourceService.getResourceContext(InternetResourceService.java:251) at org.ajax4jsf.resource.InternetResourceService.serviceResource(InternetResourceService.java:162) ...
RF-572 gives two possible solutions: using the org.ajax4jsf.portlet.AjaxFacesPortlet portlet bridge or patching the portlet bridge from Sun. Using the AjaxFacesPortlet did not work for me, I could not find the reason for the following Exception, which is thrown everytime my portlet is rendered:
19:15:47,884 ERROR [org.jboss.portal.portlet.container.org_ajax4jsf_portlet_AjaxFacesPortlet] The portlet threw an exception javax.portlet.PortletException: Error processing execute lifecycle javax.portlet.PortletException: Error processing execute lifecycle at org.ajax4jsf.portlet.AjaxFacesPortlet.doView(AjaxFacesPortlet.java:191) at javax.portlet.GenericPortlet.doDispatch(GenericPortlet.java:133) at javax.portlet.GenericPortlet.render(GenericPortlet.java:306) at org.jboss.portal.portlet.impl.jsr168.PortletContainerImpl.invokeRender(PortletContainerImpl.java:483) ...
Maybe this is just a configuration problem, it seems to be working in your environment. The second approach, patching the Sun portlet bridge, was successful. My richfaces portlet was rendered and I could see the BlueSky skin. Unfortunately, Ajax is not working in the portlet environment. A good example for demonstrating that is the TabPanel example from the RichFaces Live Demo (http://livedemo.exadel.com/richfaces-demo/richfaces/tabPanel.jsf). This example uses three different switchTypes for switching the tabs: "client", "server", and "ajax".
- "client" works, the tabs are switched without reloading.
- "server" works, the whole portal page is reloaded.
- "ajax" doesn't work, while loading the portlet the server throws this exception:
20:21:40,237 ERROR [ResourceLifecycle] Exception in PhaseListener, phase :RENDER_RESPONSE 6 : afterPhase javax.faces.FacesException: AJAX call to portlet without namespace parameter at org.ajax4jsf.portlet.context.ServletContextImpl.getNamespace(ServletContextImpl.java:102) at org.ajax4jsf.portlet.context.ServletContextImpl.getSessionPrefix(ServletContextImpl.java:222) at org.ajax4jsf.portlet.context.ServletContextImpl.getSessionAttributeNames(ServletContextImpl.java:252) at org.ajax4jsf.portlet.context.AbstractExternalContext$8.getEnumeration(AbstractExternalContext.java:457) at org.ajax4jsf.portlet.context.ContextMap.entrySet(ContextMap.java:59) at java.util.AbstractMap.containsKey(AbstractMap.java:123) ...
and when clicking on a tab, the server throws this exception:
20:21:48,633 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception java.lang.NullPointerException at com.sun.faces.portlet.LifecycleImpl.getWindowStateIdentifier(LifecycleImpl.java:524) at com.sun.faces.portlet.LifecycleImpl.restore(LifecycleImpl.java:389) at com.sun.faces.portlet.LifecycleImpl.execute(LifecycleImpl.java:226) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141) at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281) ...
So what can we do? Should we submit any bug reports? Did you find any solutions in the meantime?
holgerj: Any updates?
I downloaded your .war and try to deploy at my JbossAS which bundle portal.
I believe it is the latest stable release.
but my deployment is not successful.
Are there any customization i need to make it work?
and btw, would be please kindly give me the source of that demo project?
I would like to know how to implement a simple richfaces ajax echo portlet by myself.
thank you so much.
I have also created a Richfaces JSF portlet and deployed it to my JBoss AS 4.2.2.GA with JBoss Portal 2.6.2.GA, and the portlet shows, but I get a lot of exceptions in the log, like:
13:56:07,165 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception org.ajax4jsf.resource.ResourceNotFoundException: Resource not registered : org.richfaces.renderkit.html.iconimages.CalendarSeparator at org.ajax4jsf.resource.ResourceBuilderImpl.getResource(ResourceBuilderImpl.java:393)
13:56:38,605 ERROR [ResourceLifecycle] Exception in PhaseListener, phase :RENDER_RESPONSE 6 : beforePhase javax.faces.FacesException: AJAX call to portlet without namespace parameter at org.ajax4jsf.portlet.context.ServletContextImpl.getNamespace(ServletContextImpl.java:107) at org.ajax4jsf.portlet.context.ServletContextImpl.getSessionPrefix(ServletContextImpl.java:23