Sitebricks And SiteMesh On Google App Engine

For the past couple of weeks, I’ve been trying various web framework stacks to be used with Google App Engine. The ones that I gave a go, and gave a pass for various reasons, were Stapler (the enchilada that powers Hudson), Spring, and RestEasy + htmleasy.

The search continued and I came across Sitebricks, still in its alpha phase but it looks really promising. Simple and straightforward, nothing too magicky, and I got it working with GAE/J in no time.

To guide others who might want to give Sitebricks on Google App Engine a try, here’s what I did: (and please note that this is a miminalist guide, enough to get a simple page up and running)

  1. Using Google Plugin for Eclipse, create a new Google Web Application Project with Google App Engine enabled and Google Web Toolkit disabled.

  2. Since Sitebricks didn’t have any official release yet, I had to build the jar from the sitebricks-0.7 tag using mvn install -Dmaven.test.skip=true . Unfortunately some of the unit tests on the trunk failed so I just skipped them, hey it’s still in alpha.

  3. The above command downloaded all the dependency jars and generated a Sitebricks SNAPSHOT jar at <M2_REPO>/com/google/sitebricks . Copy the following jars to the Eclipse project’s /war/WEB-INF/lib directory and add them to the build path.

* sitebricks-0.7.jar


* guice-2.0.jar


* guice-servlet-2.0.jar


* google-collections-1.0-rc3.jar


* aopalliance-1.0.jar


* mvel2-2.0.14.jar


* dom4j-1.6.1.jar


* commons-io-1.4.jar
  1. Create the following files in src/your/package/name. GuiceInit.java

    public class GuiceInit extends GuiceServletContextListener {
    
        @Override
        public Injector getInjector() {
            return Guice.createInjector(new SitebricksModule() {
                @Override
                protected void configureSitebricks() {
                    scan(FooBar.class.getPackage());
                }
            });
        }
    }
    FooBar.java
    @At("/barkleyzone")
    public class FooBar {
    
        public String getQuote() {
            return "I have nothing against old people; I want to be one myself one day";
        }
    
        public String getName() {
            return "Charles Barkley";
        }
    }

Create FooBar.html in /war.

<div>
    ${name} said "${quote}".
</div>

Add GuiceInit servlet context listener and GuiceFilter to /war/WEB-INF/web.xml.

<filter>
    <filter-name>webFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>webFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
    <listener-class>your.package.name.GuiceInit</listener-class>
</listener>

  1. Enable sessions by adding this line in /war/WEB-INF/appengine-web.xml .

    <sessions-enabled>true</sessions-enabled>

  2. Use Eclipse Run -> Run As -> Web Application to start the application and visit http://localhost:8080/barkleyzone and you should see this message:

    Charles Barkley said "I have nothing against old people; I want to be one myself one day."

As for a page layout / templating solution, SiteMesh has always been a personal favourite.

  1. Download sitemesh-2.4.2.jar, place it in /war/WEB-INF/lib directory and add it to the build path.

Create /war/templates/main.jsp .

<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<html>
<head>
<title>Test</title>
</head>
<body>
    <decorator:body/>
</body>
</html>

Create /war/WEB-INF/decorators.xml .

<decorators defaultdir="/templates/">
    <decorator name="main" page="main.jsp">
        <pattern>/*</pattern>
    </decorator>
</decorators>

Add SiteMeshFilter to /war/WEB-INF/web.xml .

<filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  1. Use Eclipse to stop and start the application, view the HTML source of http://localhost:8080/barkleyzone and you should see the HTML layout wrapping the original div element.
Share Comments
comments powered by Disqus