How to use RichFaces 4.0 with Google App Engine

This document is going to cover the basics of using JSF 2.0 and more specifically RichFaces 4.0 on the Google App Engine (GAE) PaaS offering.  This will include general modifications needed for any JSF 2.0 application, and also some features of RichFaces to make features like skinning, and resource handling function smoothly.  It will also cover two ways to get started quickly, including our GAE Maven archetype, and how you can get your own copy of RichFaces Showcase application running there.

Restriction Basics

Google App Engine has imposed various restrictions on applications running in their cloud.  Some of these are especially troublesome to JSF.  Below is a list of the major ones effecting our efforts

  • Creation of new threads is not allowed
  • Java2D is one of the prohibited APIs
  • No write access to the file system

There are many other restricted API's and limitations.  Take a look at the GAE for Java FAQ for more.

JSF 2.0 Changes

GAE is a limited, and specialized environment with various rules, and API restrictions.  Among these are resource limits, and requiring a single threaded application.  In order to run any JSF 2.0 application on GAE you have some changes that need to be made.  GAE maintains a "Cookbook" page to help with this, but it is not always up to date.

Turn off multi-threaded startup for Mojarra

In your web.xml:

 

   <context-param>
        <param-name>com.sun.faces.enableThreading</param-name>
        <param-value>false</param-value>
   </context-param>

 

If you turn off multi-threading for Mojarra you must also set the PROJECT_STAGE to production so the resource handlers can load properly.

 

    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Production</param-value>
    </context-param>

Client side state saving

JSF also has issues on GAE with session state replication, and because of that client state saving is the best approach.  To enable this update the web.xml

 

    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>

RichFaces Integration

The most serious restriction for RichFaces was around the Java2D API.  We use this extensively for our skinning feature.  In order to work around this issue we have developed a resource maven plugin that generates a skinning resource statically.  This has the added benefit of allowing for separate hosting of your resources to improve performance. 

 

This maven plugin does quite a bit for you:

  • Substitute skin parameters in CSS for all skins used by the application
  • Compress CSS files
  • Provide relative URLs in CSS
  • Generate all skin images
  • Generates descriptor for all processed files. RichFaces framework use this descriptor to point to appropriate resources (e.g. placed on external server/CDN)

 

To see a sample of the plugin in action check out the maven-resources-plugin section of the RichFaces GAE archetype pom.xml.  You can see more details in the documentation <LINK TO DOCS>.

 

Now all that is needed is to let RichFaces know where you static resources are located ( set in the plugin config ).  This is done through a context parameter in the web.xml:


    <context-param>
        <param-name>org.richfaces.staticResourceLocation</param-name>
        <param-value>#{facesContext.externalContext.requestContextPath}/static-resources/#{resourceLocation}</param-value>
    </context-param>

 

Note: the #{resourceLocation} is an implicit variable for referencing the relative paths for the static resources generated by the plugin.

RichFaces Limitations

Due to restrictions from GAE there a couple of features that do not function, or could be handled better through GAE mechanisms

 

  • The rich:fileUpload component does function on GAE with MyFaces,
    • With Mojarra fileupload does function correctly, but there are some integration points that need tuning.
    • There is also GAE's own approach to this described on their wiki.
  • The rich:push component does not function correctly on GAE . 
    • Push requires special GAE-specific integration points that have not been implemented yet.

Uploading and Launching Your Application

There is really no special steps required here.  You can follow all of the instructions and guidelines provided back GAE.  There are a few things to keep in mind though:

 

  • Be sure to register and set your application's name with GAE and in your appengine-web.xml file.
  • Make sure you updated the version in the appengine-web.xml file before redeploying

 

To upload your application you can either use the standard GAE SDK, or integrate the maven-gae-plugin as we have for the showcase example and the GAE archetype.  To use the SDK you can execute the GAE SDK tool appcfg update <path to exploded archive application>.  If using the Maven plugin you use it's goals to deploy locally, or remotely to you account.

 

RichFaces Showcase Application

Our own RichFaces Showcase demo is fully deployable to GAE!  In fact we host our own online version there.  It can be accessed either through http://richfaces.org/demo or http://richfaces-showcase.appspot.com/

 

All the details for how to build and upload your own version is available in the RichFaces Showcase readme.txt file.

 

Note regarding the hosted version of the showcase:  The hosted RichFaces Showcase is using Mojarra 2.0.3.  This is for a couple of reasons. With MyFaces 2.0.4 the fileupload component does not function correctly, and with Mojarra 2.0.4 there were addition GAE integration issues.  We'll update the showcase and the versions as the implementations improve integration.

RichFaces GAE Archetype

We also have a ready made Maven archetype available to generate your own stub GAE application.  For all the details you can review the archetype's readme.txt file.  However creating the project is as easy as executing:

 

mvn archetype:generate -DarchetypeGroupId=org.richfaces.archetypes 
                       -DarchetypeArtifactId=richfaces-archetype-gae 
                       -DarchetypeVersion=<richfaces-version> 
                       -DgroupId=<yourGroupId> 
                       -DartifactId=<yourArtifactId> 
                       -Dversion=<yourAppsVersion>

 

Note that the artifact given will be your applications name in the appengine-web.xml file!

 

You can then simply run mvn clean install in your new project's root directory, and follow the instructions for uploading your application.  You can also easily import and work with your application is an IDE, especially JBoss Tools.

Additional  Optimizations

Below is a listed of various optimizations that are optional but may improve your applications performance or behavior on GAE.

 

<TBD>