Posts tagged jsf2
Google App Engine with JSF2, CDI
4Last night I wanted to play around with the Google App Engine. Google’s cloud service should ring a bell? Don’t worry if it doesn’t, you can read more about it and use this tutorial as your first GAE-project!
Due to my interest in JEE6-technologies, I was interested whether the latest Google App Engine (1.4.3) supported the latest technologies in Java: JSF2 for the view layer, and CDI ( Contexts and Dependency Injection for the Java EE Platform ) to wire everything up.
In this article I will briefly discuss what problems I have encountered while setting up this environment.
Shortcut: If you’re only interested in the result, and want to get started right away, you can download the full eclipse project here. No GAE or CDI dependencies!
Project Setup
JSF2 on the Google App Engine
To get started, I advise you to follow the guide ‘Configuring JavaServer Faces 2.0 to run on the Google App Engine Using Eclipse‘ described on the Google website. It is pretty much complete, well documented with screenshots, and a breeze to follow.
The guide will set up your IDE, configure the Google App Engine plugin, download and configure the required libraries for setting up JSF2 on the Google App Engine.
Adding CDI
Download Weld 1.1.1-FINAL. Extract the download, it contains the following libraries which you need to add to the build path:
- cdi-api.jar
- weld-api.jar
- weld-core.jar
- weld-servlet.jar
Add the following listener to your web.xml :
<listener>
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
To finalize the configuration of CDI in your GAE-application, add an empty beans.xml file to your WEB-INF folder. This is needed by default by CDI to enable classpath scanning.
Problems encountered
Startup fails – InitialContext
After following the Google tutorial on setting up JSF2 on GAE, you’ll notice something odd. Yes, your application isn’t starting up!
This is the stracktrace:
WARNING: Error starting handlers java.lang.NoClassDefFoundError: javax.naming.InitialContext is a restricted class. Please see the Google App Engine developer's guide for more details. at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51) at com.sun.faces.config.WebConfiguration.processJndiEntries(WebConfiguration.java:578)
As you can see, the com.sun.faces.config.WebConfiguration class tries to load up an InitialContext in the processJndiEntries method. The InitialContext class is not allowed by the Google App Engine for obvious reasons.
When we take a look into the WebConfiguration.java class ( love open-source! ), we can clearly see the InitialContext being loaded:
private boolean canProcessJndiEntries() {
try {
Util.getCurrentLoader(this).loadClass("javax.naming.InitialContext");
} catch (Exception e) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine(
"javax.naming is unavailable. JNDI entries related to Mojarra configuration will not be processed.");
}
return false;
}
return true;
}
The App Engine is freaking out and throws the restricted class exception. Thanks to open-source we can clearly see what’s going on, and modify it to our own needs. Since we don’t need any JNDI-lookups, we can safely remove this method.
Copy paste the original java sourcefile to the same package in your project (com/sun/faces/config/), and comment out all references to the InitialContext.
You can download the result, for version jsf-impl-2.0.2-FCS.jar, here.
Enable Sessions
Sessions are disabled by GAE by default. The following exception is thrown.
java.lang.RuntimeException: Session support is not enabled in appengine-web.xml. To enable sessions, puttrue in that file. Without it, getSession() is allowed, but manipulation of sessionattributes is not. at com.google.apphosting.utils.jetty.StubSessionManager$StubSession.throwException(StubSessionManager.java:77) at com.google.apphosting.utils.jetty.StubSessionManager$StubSession.setAttribute(StubSessionManager.java:65)
The exception is well documented; as mentioned, you need to put
JSF configuration
- GAE supports server state saving, so use the javax.faces.STATE_SAVING_METHOD param
- Projectstage can be any one of the phases
- The expressionfactory needs to be explicitly set due to a GAE-bug
- We enable the xml validation checks
- Spawning threads is disallowed in GAE. By setting the com.sun.faces.enableThreading param to false, JSF will not spawn childthreads
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.enableThreading</param-name>
<param-value>false</param-value>
</context-param>
References
- Google Guide to configuring JSF 2.0 to run on the Google App Engine. I used this guide myself to get started, but some errors I encountered aren’t discussed in it. (link)
- Article discussing the solution to the ‘javax.naming.InitialContext is a restricted class’ problem. (link)
- JavaServer Faces 2.0 and Google App Engine Compatibility Issues (link)
RichFaces 4 Alpha Released
12Today, the RichFaces 4 Alpha 2 was released. For an overview of what’s new in JSF2 and the possibilities, check out this blog by Andy Schwartz for a complete review with lots of links and documentation.
Quote from the Richfaces Project Page
RichFaces is a component library for JSF and an advanced framework for easily integrating AJAX capabilities into business applications.
- 100+ AJAX enabled components in two libraries
- a4j: page centric AJAX controls
- rich: self contained, ready to use components
- Whole set of JSF benefits while working with AJAX
- Skinnability mechanism
- Component Development Kit (CDK)
- Dynamic resources handling
- Testing facilities for components, actions, listeners, and pages
- Broad cross-browser support
- Large and active community
JSF 2 and RichFaces 4
We are working hard on RichFaces 4.0 which will have full JSF 2 integration. That is not all though, here is a summary of updates and features:
- Redesigned modular repository and build system.
- Simplified Component Development Kit with annotations, faces-config extensions, advanced templates support and more..
- Ajax framework improvements extending the JSF 2 specification.
- Component review for consistency, usability, and redesign following semantic HTML principles where possible.
- Both server-side and client-side performance optimization.
- Strict code clean-up and review.
I followed the tutorial on how to get a project up and running from this JBoss Community article and started work on a clean skeleton. On this blank project I will be experimenting with JSF2 and richfaces components in the near future.
With this blank project in mind, I created following architecture:
- Maven2 Project
- Reference JSF2 API and IMPL
- RichFaces 4.0.0.Alpha2 component library
You can immediatly start experimenting by importing this Maven2 project in your favourite IDE (mvn eclipse:eclipse goal is configured). Have fun!