InfoQ

Article

Developing Portlets using JSF, Ajax, and Seam (Part 1 of 3)

Posted by Wesley Hales on Aug 06, 2008

Community
Java
Topics
Portal/CMS
Tags
JSF

If you are just starting to look at using a portal solution, or you want to learn how easy it is to integrate a new or existing JSF application into a portal environment, then this article is for you.

Portals have gained a lot of ground over the past few years, both in the enterprise and with the new enhancements of the portlet 2.0 (JSR 286) specification. The new 2.0 portlets allow you many freedoms in aggregating different applications and presenting them in different windows on one page. And of course, you get authentication, sophisticated personalization features, and better ways of handling AJAX out of the box.

With the JSR 301 portlet bridge specification, we now have a standard way of running JSF applications as both 1.0 and 2.0 portlets. The portlet bridge handles the portal Action/Render paradigm to properly handle the JSF lifecycle. While this tutorial is mainly to show you how easy it is to configure and develop a JSF portlet, I will also be revealing the new JBoss Portlet Container 2.0 and some of it’s cool new features.

This is the first in a series of 3 articles which will range from basic JSF portlet and portal knowledge through to advanced usage of AJAX and Seam in a portlet environment.

Now, let’s get on with it.

Project Setup

Development Tools:

To follow along with this guide download the latest version of Maven. (I am using 2.0.9)
Install Maven 2.0.9+
Set the Maven binaries on your path

Server and binaries used in examples:

JBoss Portal’s Portlet Container 2.0
JBoss Portlet Bridge Beta3

Currently, JBoss Portlet Bridge is the only implementation of the JSR 301 spec that allows you to run any combination of JSF, RichFaces, and Seam. The Maven configuration for your project is setup to download JBoss AS and JBoss Portlet Container 2.0 packaged together. If you want to download them seperately, you can find them here. Otherwise, allow Maven a few minutes to download the proper files during the next steps.

Note - This portlet can also be run in the current 2.6.5.SP1 version of JBoss Portal. I am using the JBoss Portlet Container 2.0 for this article, but the bridge works in either. You can read how to configure to run in any version of JBoss Portal here.

The following Maven archetype is a simple way to get up and running quickly with a starter (or template) project. Once you run this command, you will have everything you need to develop and follow this guide.

Open a terminal and run:

mvn archetype:generate -DarchetypeGroupId=org.jboss.portletbridge.archetypes
-DarchetypeArtifactId=1.2-basic
-DarchetypeVersion=1.0.0.B3 -DgroupId=org.whatever.project -DartifactId=myprojectname
-DarchetypeRepository=http://repository.jboss.org/maven2/ -Dversion=1.0.0.B3

Now navigate to the directory where you created your new project. If you use the example above, it would be the "myprojectname" directory. Take a look around, browse through the files that were just created. You will see the basic Maven folder structure with source code for this tutorial. Now would also be a good time to fire up your favorite IDE and import this Maven project.

Portlet Bridge Configuration Requirements

From here, development will be much like developing any other JSF application in the servlet world. The only differences will be dealing with things like Single Sign-On, the portletContext and accessing variables that are needed for things like namespacing, and window modes in your portlet like 'Help' and 'Edit' modes. I'm not going to get into the extreme details of the portlet world, but I will give you the information needed to do basic development. If you need more information about portlets please read the JSR 168 or JSR 286 specifications.

The cool thing about the JBoss Portlet Bridge is that, it’s not a portlet. It’s simply a mediator between the portlet and JSF worlds. Your JSF application is the portlet. Your WEB-INF directory will contain 3 or 4 extra xml files along with the bridge jars, but everything else stays the same as the servlet version of your application. The only differences are in the following configuration files:

portlet.xml

<portlet>
...v <portlet-class>
javax.portlet.faces.GenericFacesPortlet
</portlet-class>
<init-param>
<name>javax.portlet.faces.defaultViewId.view</name>
<value>/home.xhtml</value>
</init-param>
<init-param>
<name>javax.portlet.faces.defaultViewId.edit</name>
<value>/jsf/edit.xhtml</value>
</init-param>
<init-param>
<name>javax.portlet.faces.defaultViewId.help</name>
<value>/jsf/help.xhtml</value>
</init-param>
...
</portlet>

web.xml

<context-param>
<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
<param-value>
org.jboss.portletbridge.application.FaceletPortletViewHandler
</param-value>
</context-param>
<context-param>
<param-name>javax.portlet.faces.renderPolicy</param-name>
<param-value>
ALWAYS_DELEGATE
</param-value>
</context-param>

faces-config.xml

 <application>
<view-handler>
org.jboss.portletbridge.application.PortletViewHandler
</view-handler>
<state-manager>org.jboss.portletbridge.application.PortletStateManager</state-manager>
</application>

The above settings are already applied in the Maven archetype which you just set up. So now it's time to compile the project and deploy it to JBoss Portal.

Running the demo application

Compile your new project and deploy in 2 steps:

Step 1: mvn install cargo:start -Premote-portal -Dpc20

This command will take a few minutes to download the server+portal bundle so please wait until you see the following before taking the next step:

*Note - you will also see a PortletException just before the server starts. This is normal and is part of the Portlet Container 2.0 demo's FailDuringInitPortlet.

Next open a second terminal window, navigate to the JSF portlet project root and run:

Step 2: mvn cargo:deploy -Premote-portal -Dpc20

The command line parameters instruct cargo on where the JBoss+Portal bundle is located and what version of portal you are running. You can also run this example on the latest version of the JSR 168-compliant JBoss Portal 2.6.5.SP1. For more information and Maven commands see section the JBoss Portlet Bridge documentation found here. To view the deployed JSF portlet visit: http://localhost:8080/simple-portal/demo/jsr-301.jsp

JSF Portlet Development

Now, let's look at a few things that tie portlet and JSF development together.

Viewing your portlet as a normal webapp

The portlet bridge is transparent when viewing your application as a servlet-side web app. As a portlet developer, it's nice to have a sanity check every once and a while to ensure that what you're developing is not blowing up because you're running it in a portal environment. To view this demo application, or any application deployed with the bridge, you can visit http://localhost:8080/JSFRIPortlet/home.jsf

Namespacing

The bridge handles the namespacing combinations of JSF in the portal environment. In situations where you need to use the id of an element in your JSF/xhtml markup, you would normally see something like 'form1:myBtn' in the rendered markup. But now with the bridge namespacing you will see something similar to:
jbpns_2fdefault_2fNews_2fStories_2fStoryTemplateWindow12snpbj:_viewRoot:form1:myBtn

To overcome this, you can use the following expression in your Facelets page to prepend the namespace to your javascript code:
document.getElementById('#{facesContext.externalContext.response.namespace}the_rest_of_JSF_ID');

Please note that since this uses the portletResponse, once you try to view this page on the servlet application side you will get an exception. To avoid this, you need to check for the type of response in your backing bean and assign a new "safe" namespace variable for the UI.

preserveActionParams

When preserveActionParams is set to TRUE in your web.xml, the bridge must maintain any request parameters assigned during the portlet's action request. The request parameters are maintained in the "bridge request scope". When this attribute isn't present or is FALSE the action's request parameters are only maintained for the duration of the portlet request scope.

<init-param>
<param-name>javax.portlet.faces.preserveActionParams</param-name>
<param-value>true</param-value>
<init-param>

Using something like #{request.yourParam} in your Facelets page will utilize this setting.

Excluding Attributes from the Bridge Request Scope

When your application uses request attributes on a per request basis and you do not want that particular attribute to be managed in the extended bridge request scope, you must use the following configuration in your faces-config.xml. Below you will see that any attribute namespaced as foo.bar or any attribute beginning with foo.baz(wildcard) will be excluded from the bridge request scope and only be used per that application's request:

  <application>
<application-extension>
<bridge:excluded-attributes>
<bridge:excluded-attribute>foo.bar</bridge:excluded-attribute>
<bridge:excluded-attribute>foo.baz.*</bridge:excluded-attribute>
</bridge:excluded-attributes>
</application-extension>
</application>

Or you can use the javax.portlet.faces.annotation.ExcludeFromManagedRequestScope annotation to accomplish the same thing by annotating the object class that you don't want to be included in the request.

Conclusion

As you can see, the JSR 301 specification not only makes it simple to set up an existing JSF web application as a portlet, but also gives you (the developer) a way to manage and handle the differences between JSF and portlets. With that said, the spec is still under heavy review and revisioning. As of the writing of this article, Early Draft Review 3 is the latest public version but there have already been many advancements on top of this revision inside the JSR 301 Expert Group. One of the larger enhancements to the bridge is portlet-mode navigation and state which will be implemented in the the next version (Beta 4) of the JBoss Portlet Bridge.

To find out more about the project, compatible versions that the bridge supports, or to participate in the community forums please visit our project page and blog.

Fatal Error by Venkat Kodali Posted Oct 6, 2008 8:38 AM
Re: Fatal Error by Wesley Hales Posted Oct 7, 2008 4:13 PM
Re: Fatal Error by Roel Slieker Posted Dec 8, 2008 5:05 AM
Getting Build Errors by J Crisp Posted Nov 17, 2008 10:33 AM
Re: Getting Build Errors by xuesong mei Posted Dec 2, 2008 10:45 AM
Re: Getting Build Errors by Wesley Hales Posted Jan 9, 2009 10:34 AM
  1. Back to top

    Fatal Error

    Oct 6, 2008 8:38 AM by Venkat Kodali

    Hi Wesley,

    Nice article, I am getting this error while build. Appreciate your help thanks


    [INFO] [cargo:start]
    [INFO] ------------------------------------------------------------------------
    [ERROR] FATAL ERROR
    [INFO] ------------------------------------------------------------------------
    [INFO] Error while expanding C:\test\jboss\DashboardPortal\DashboardPortal\targe
    t\installs\jboss-portletcontainer-2.0.0-jbossas42.tar.gz
    Unexpected end of ZLIB input stream
    [INFO] ------------------------------------------------------------------------
    [INFO] Trace
    in cargo code: Error while expanding C:\test\jboss\DashboardPortal\DashboardPort
    al\target\installs\jboss-portletcontainer-2.0.0-jbossas42.tar.gz

  2. Back to top

    Re: Fatal Error

    Oct 7, 2008 4:13 PM by Wesley Hales

    Looks like your download probably died early (reset) or it was corrupt for some reason. Just run 'mvn clean' and go through the process again.

  3. Back to top

    Getting Build Errors

    Nov 17, 2008 10:33 AM by J Crisp

    I am trying to work through the article but getting an error:

    C:\>mvn install cargo:start -Premote-portal -Dpc20
    [INFO] Scanning for projects...
    [INFO] Searching repository for plugin with prefix: 'cargo'.
    [INFO] ------------------------------------------------------------------------
    [ERROR] BUILD ERROR
    [INFO] ------------------------------------------------------------------------
    [INFO] The plugin 'org.apache.maven.plugins:maven-cargo-plugin' does not exist o
    r no valid version could be found

    I setup Maven as instructed above. Am I missing something else?

  4. Back to top

    Re: Getting Build Errors

    Dec 2, 2008 10:45 AM by xuesong mei

    Yes, I have the same problem.

  5. Back to top

    Re: Fatal Error

    Dec 8, 2008 5:05 AM by Roel Slieker

    For some reason the automated downloading gets abrupted, and it's not due to bad network.
    Just download the files downloads.sourceforge.net/jboss/jboss-portletco... and
    downloads.sourceforge.net/jboss/jboss-portal-2.... manually and put in ./target/installs
    Run "mvn install cargo:start -Premote-portal -Dpc20" again and it will work.

  6. Back to top

    Re: Getting Build Errors

    Jan 9, 2009 10:34 AM by Wesley Hales

    Make sure you are in the archetype directory that has been created.

Educational Content

Brian Marick on 4 Challenges and 5 Guiding Values of Agile Software Development

Brian Marick takes us through a quick tour of the most important values and challenges to adopting Agile successfully (they aren't the typical challenges and values we hear in the community).

Are You a Software Architect?

The line between development and architecture is tricky. Does it exist at all? Is an ivory tower actually needed? There's a balance in the middle, but how do you move from developer to architect?

Agile – A Way of Life and Pragmatic Use of Authority

The word 'authority' sometimes produces an allergic response in hard-line agilists. Freedom and authority – both are bad if misused and both are good if used in right spirit for a noble cause.

Getting Started with Grails, Second Edition

"Getting Started with Grails" brings you up to speed on this modern web framework. Companies as varied as LinkedIn, Wired, and Taco Bell are all using Grails. Are you ready to get started as well?

Using ITIL V3 as a Foundation for SOA Governance

Those familiar with only ITIL V2 often scoff at the thought that ITIL could serve as a governance framework for SOA. With ITIL V3, the focus of the framework shifted towards service-orientation.

Adrian Colyer on AspectJ, tc Server and dm Server

SpringSource CTO Adrian Colyer discusses AspectJ, SpringSource's dm Server and tc Server products, OSGi and Scrum.

Adam Wiggins on Heroku

Heroku's Adam Wiggins talks about Rails, Background Jobs, Add-Ons, Ruby, and how Heroku manages to work around Ruby's inefficiencies using Erlang and other languages.

SOA as an Architectural Pattern: Best Practices in Software Architecture

For Grady Booch the foundation of a good architecture is patterns, SOA being just one of many patterns. In this Second Life presentation, Booch attempts to bring more clarity on what architecture is.