In this tutorial, we will show you how to develop and deploy a JSF 2.0 web application in Google App Engine (GAE) environment.

Tools and technologies used :

  1. JDK 1.6
  2. Eclipse 3.7 + Google Plugin for Eclipse
  3. Google App Engine Java SDK 1.6.3.1
  4. JSF 2.1.7
Note
This example is going to reuse this JSF 2.0 hello world example, modify it and merge it with this GAE + Java example.

1. New Web Application Project

In Eclipse, create a new Web Application project, named as “JSFGoogleAppEngine“.

generate a new web application GAE project

“Google Plugin for Eclipse” will generate a sample of GAE project structure.

2. JSF 2 Dependencies

To use JSF 2 in GAE, you need following jars

  1. jsf-api-2.1.7.jar
  2. jsf-impl-2.1.7.jar
  3. el-ri-1.0.jar

Copy and put it in “war/WEB-INF/lib” folder.

gae jsf2 dependency libraries

Right click on project folder, select “Properties“. Select “Java Build Path” -> “Libraries” tab, click “Add Jars” button and select above jars.

gae jsf2 java build path
Note
You need to put this el-ri-1.0.jar, otherwise, you will hit error message – Unable to instantiate ExpressionFactory ‘com.sun.el.ExpressionFactoryImpl’.

3. JSF Managed bean

3.1 Delete plugin generated JSFGoogleAppEngineServlet.java, you don’t need this.

3.2 Create a managed bean.

File : src/com/mkyong/HelloBean.java

package com.mkyong;
 
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
 
import java.io.Serializable;
 
@ManagedBean
@SessionScoped
public class HelloBean implements Serializable {
 
	private static final long serialVersionUID = 1L;
 
	private String name;
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
}

3.3 Create a new WebConfiguration.java.

JSF 2 is using “javax.naming.InitialContext” that’s not support in GAE.

To solve this, you need to get a copy of the JSF’s source code, clone the WebConfiguration.java, comment methods that are using “javax.naming.InitialContext” class, put it in “src/com/sun/faces/comfig/WebConfiguration.java“. Now, your newly created WebConfiguration.java class will overload the original WebConfiguration.java.

I don’t think GAE team will white-list this jar, just hope JSF’s team can fix this in future release.

4. JSF Pages

4.1 Create hello.xhtml page, accept a user input and pass it to helloBean.

File : war/hello.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html">
 
<h:head>
	<title>GAE + JSF</title>
</h:head>
<h:body>
	<h1>Google App Engine + JSF 2.0 example - hello.xhtml</h1>
	<h:form>
		<h:inputText value="#{helloBean.name}"></h:inputText>
		<h:commandButton value="Welcome Me" action="welcome"></h:commandButton>
	</h:form>
</h:body>
</html>

4.2 Create welcome.xhtml page, display the user input from hellobean.

File : war/welcome.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html">
 
<h:head>
	<title>GAE + JSF</title>
</h:head>
<h:body bgcolor="white">
	<h1>Google App Engine + JSF 2.0 example - welcome.xhtml</h1>
	<h4>Welcome #{helloBean.name}</h4>
</h:body>
</html>

4.3 Delete the plugin generated index.html file, you don’t need this.

5. web.xml

Update web.xml, integrate JSF 2.

File : web.xml

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">
 
	<display-name>JavaServerFaces</display-name>
 
	<!-- GAE 1.6.3 cannot handle server side (JSF default) state management. -->
	<context-param>
		<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
		<param-value>client</param-value>
	</context-param>
 
 
	<!-- Change to "Production" when you are ready to deploy -->
	<context-param>
		<param-name>javax.faces.PROJECT_STAGE</param-name>
		<param-value>Development</param-value>
	</context-param>
 
	<!-- Welcome page -->
	<welcome-file-list>
		<welcome-file>faces/hello.xhtml</welcome-file>
	</welcome-file-list>
 
	<!-- JSF mapping -->
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
 
	<!-- Map these files with JSF -->
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>/faces/*</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.jsf</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.faces</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.xhtml</url-pattern>
	</servlet-mapping>
 
</web-app>
Note
GAE do not support server side state management, so, you need to define “javax.faces.STATE_SAVING_METHOD” to “client“, to avoid of this “View /hello.xhtml could not be restored” error message in GAE production environment.

6. Enable Session in GAE

Update appengine-web.xml, enable session support, JSF need this.

File : appengine-web.xml

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
  <application></application>
  <version>1</version>
 
	<sessions-enabled>true</sessions-enabled>
 
</appengine-web-app>

7. Directory Structure

Review final directory structure.

final directory structure

8. Run on Local

Right click on the project, run as “Web Application”.

URL : http://localhost:8888/hello.jsf

local output

Click on the button.

local output

10. Deploy on GAE

Update appengine-web.xml file, add your App Engine application ID.

File : appengine-web.xml

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
  <application>mkyong-jsf2gae</application>
  <version>1</version>
 
	<sessions-enabled>true</sessions-enabled>
 
</appengine-web-app>

Select project, click on Google icon, “Deploy to App Engine“.

deploy on GAE

URL : http://mkyong-jsf2gae.appspot.com/hello.jsf

gae production output

Download Source Code

Due to large file size, all JSF and GAE jars are excluded.

Download – JSF2-GoogleAppEngine-Example.zip (42 KB)

References

  1. JSF and GAE compatible issues
  2. JSF 2 configuration on Google App
  3. Google App Engine with JSF 2 + CDI
  4. Getting start with Google App and JSF
  5. JSF 2.0 hello world example
  6. Oracle : JavaServer Faces development tutorial
Tags :
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider making a donation to this charity, thanks.

Related Posts

Popular Posts