InfoQ

InfoQ

Article

My Bookmarks

Login or Register to enable bookmarks for unlimited time.

The content has been bookmarked!

There was an error bookmarking this content! Please retry.

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

Posted by Wesley Hales on Aug 06, 2008

Sections
Development,
Operations & Infrastructure
Topics
Java ,
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
Re: Fatal Error by Wesley Hales Posted
Re: Fatal Error by Roel Slieker Posted
Getting Build Errors by J Crisp Posted
Re: Getting Build Errors by mei xuesong Posted
Re: Getting Build Errors by Wesley Hales Posted
  1. Back to top

    Fatal Error

    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

    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

    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

    by mei xuesong

    Yes, I have the same problem.

  5. Back to top

    Re: Fatal Error

    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

    by Wesley Hales

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

Educational Content

Questions for an Enterprise Architect

Erik Dörnenburg answers: What is Enterprise and Evolutionary Architecture?, discussing 4 issues: Turning strategy into execution, Ensuring conformance, Where do the architects sit? Buying or building?

Wrap Your SQL Head Around Riak MapReduce

Sean Cribbs explains what Map-Reduce and Riak are, why and how to use Map-Reduce with Riak, and how to convert SQL queries into their Map-Reduce equivalents.

Polyglot Persistence for Java Developers - Moving Out of the Relational Comfort Zone

Chris Richardson shows how he ported a relational database to three NoSQL data stores: Redis, Cassandra and MongoDB.

The Golden Circle – Why How What

Jean Tabaka challenges the audience to reflect on what Agile practices they are employing, how they are using them, ending with the questions “Why have their organization chosen to go Agile?

The Web Platform as a Limitless Pool of Innovation, with Andreas Gal

Andreas talks about the benefits of the Open Web and how it compares to proprietary stacks. He also talks about various projects that push the envelope like Boot to Gecko, Broadway and pdf.js.

Hadoop and NoSQLin a Big Data Environment

Ron Bodkin discusses early adoption of Hadoop, NoSQL and describes MapReduce and related libraries and Frameworks. Other topics include Hive, Pig, multi tenancy, and security in a big data environment

Spring and Platform Interoperability

Stephen Bohlen explains how Spring helps with interoperability between Java and .NET, demoing it with the help of a sample application.

How to Stop Writing Next Year's Unsustainable Piece of Code

Guilherme Silveira mentions some of the turning points in project development that may affect the quality of the code offering advice on avoiding writing crappy code.