Wednesday, October 28, 2009

JAVA: Struts 2 on Google App Engine

1. Eclipse IDE ver. 3.5
2. Googe App Engine Java SDK 1.2.5 and Google Plugin for Eclipse
2. Latest Release of Struts2 framework (note: used the the release)


1. Create a new Web Application Project in Eclipse.
1.1. Go to File-New-Web Application Project
1.2. Enter the Project name and Package. Uncheck the "Use Google Web Toolkit".

2. Add the following Struts2 libraries to /WEB-INF/lib/. Also, add these libraries to Java Build path (Right click "Project Name"->"Build Path"->"Configure Build Path...". Go to "Libraries" tab and click "Add JARS.. button to add the needed libraries).


3. Modify the auto-generated appengine-web.xml (to enable the sessions and ssl).

<appengine-web-app xmlns="">

<!-- Configure java.util.logging -->
<property name="java.util.logging.config.file" value="WEB-INF/">



4. Modify the web.xml.

<web-app xsi=""
schemalocation="" version="2.5">





5. Set the OgnlRuntime Security Manager.
Note that if you run the application after doing procedure 4, you will get OgnlException. To resolve this , implement an ServletContextListener which will set OGNL security manager to null when the context is initialized.

package net.gae.struts2den.common;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import ognl.OgnlRuntime;

public class InitListener implements ServletContextListener,
HttpSessionListener, HttpSessionAttributeListener {

public void contextInitialized(ServletContextEvent sce) {

public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub


public void sessionCreated(HttpSessionEvent arg0) {
// TODO Auto-generated method stub


public void sessionDestroyed(HttpSessionEvent arg0) {
// TODO Auto-generated method stub


public void attributeAdded(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub


public void attributeRemoved(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub


public void attributeReplaced(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub



Note: in web.xml (of procedure 4 ), an entry for InitListener is already implemented as


6. Create struts.xml in src folder


<constant name="struts.ui.theme" value="simple">

<package name="helloworld" namespace="/helloworld" extends="struts-default">
<result name="failed">/WEB-INF/jsp/myapp1/failed.jsp

<!-- http://localhost:8080/helloworld/HelloWorld.action -->
<action name="HelloWorld" class="net.gae.struts2den.action.HelloWorld">


7. Create the HelloWorld action (net/gae/struts2den/action/

package net.gae.struts2den.action;
import com.opensymphony.xwork2.ActionSupport;

public class HelloWorld extends ActionSupport {

public static final String MESSAGE = "Struts is up and running ...";

public String execute() throws Exception {
return SUCCESS;

private String message;

public void setMessage(String message){
this.message = message;

public String getMessage() {
return message;

8. Create the helloworld.jsp (WEB-INF/jsp/helloworld.jsp)

<h2><s:property value="message"></s:property></h2>

9. Run the application and open http://localhost:8080/helloworld/HelloWorld.action and see what happens!

sample application at: