Spring 3.0 with Google App Engine

For one of my final classes as an undergraduate student at Georgia Tech I’m working on a Java based webapp to be hosted in the cloud. I’ve chosen Google App Engine for its Java support and the fact that I can use if for free.  The app will make use of the Spring framework which just released version 3.0 and use JSP and JSTL for the presentation layer.  I’ve decided to post a little tutorial on getting up an running with Google App Engine (GAE), Spring 3.0, and Eclipse so that hopefully I (and anyone else that reads this) can avoid some of the pitfalls I ran into on the initial project setup.

Setting up the project in Eclipse

  1. First, you will need to set up the GAE plugin for Eclipse.  Google provides easy instructions for this here.  At the time of this posting, the current version of the SDK should be 1.3.1.
  2. Create a new project in your Eclipse workspace of type Google Web Application Project
    Choose "Web Application Project" from the Google Folder in the New Project Wizard

    The poject type is under the "Google" folder

    Do not use the Google Web Tool Kit and be sure to use the latest version of the SDK

    Enter the project settings

    You should now have a project with the following setup:

    These are the files the plugin sets up for you automatically

    Inital project structure

    The project is now set up, you can run the server by clicking the “Debug” button in Eclipse and visiting localhost:8888 in your browser.

  3. Before we start setting up Spring, let’s clean out some of the things in the project we won’t need.  You can delete the GAESpringProjectServlet.java file and change the file war/WEB-INF/web.xml to:
    <?xml version="1.0" encoding="utf-8"?>
    
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    
    </web-app>
  4. Now that the project is clean we can add in the libraries needed by the Spring framework. Download Spring from the springsource website.  You will also need commons-logging.jar and xalan.jar.  We don’t need to worry about the JSTL jars because GAE includes them for you. Add the following into the war/WEB-INF/lib folder for your project and add them to the build path (the file names have the version information left off, it should be “-3.0.0.RELEASE” for the spring jars):
    1. org.springframework.asm.jar
    2. org.springframework.beans.jar
    3. org.springframework.context.jar
    4. org.springframework.core.jar
    5. org.springframework.expression.jar
    6. org.springframework.web.servlet.jar
    7. org.springframework.web.jar
    8. commons-logging.jar
    9. xalan.jar
  5. Now it’s time to set up the configuration files for Spring.  First war/WEB-INF/web.xml:
    <?xml version="1.0" encoding="utf-8"?>
    
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    
    	<servlet>
    		<servlet-name>dispatcher</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>dispatcher</servlet-name>
    		<url-pattern>/a/*</url-pattern>
    	</servlet-mapping>
    
    </web-app>

    The dispatcher servlet handles all user requests and passes them along to the correct controller. The url mapping is to anything under the /a/ directory because of a bug with GAE.  The development server will not accept the url pattern of /* so in development you must add a prefix.  You can remove the /a before you deploy to a production GAE instance.

  6. Now create the file war/WEB-INF/dispatcher-servlet.xml and add the contents:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
     <context:component-scan base-package="com.acrhodes.gaespringproject.controllers" />
    
     <bean id="viewResolver"
     class="org.springframework.web.servlet.view.InternalResourceViewResolver"
     p:prefix="/WEB-INF/views/" p:suffix=".jsp" >
     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
     </bean>
    
    </beans>

    This sets several things up for us.  First, the context:component-scan tag tell spring to search the “com.acrhodes.gaespringproject.controllers” package for classes marked with the @Controller annotation so that we don’t have to set them up explicitly in the xml.  The viewResolver bean sets up our views to use JSTL and to return the jsp /WEB-INF/views/home/home.jsp when the view name “home/home” is given.

  7. Our final configuration file will tell Spring that we are using annotations to manage all of the bean mapping.  Add the file war/WEB-INF/applicationContext.xml with the contents:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    
    http://www.springframework.org/schema/context
    
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    <context:annotation-config/>
    
    </beans>
  8. Now we are ready to start developing our application.  Create a new package “com.acrhodes.gaespringapplication.controllers” that will house all of the controller classes and create a new HelloController class in it.  HelloController will be a simple login/logout service using the Google User Service.  Add the following code to the class:
    @Controller
    @RequestMapping("/hello")
    public class HelloController {
    
        private UserService userService = UserServiceFactory.getUserService();
    
        @RequestMapping(method = RequestMethod.GET)
        public String hello(HttpServletRequest request, ModelMap model)
        {
            String url = request.getRequestURI();
            String message;
    
            if(request.getUserPrincipal() != null)
            {
                message = new StringBuilder()
                .append("Hello, ")
                .append(request.getUserPrincipal().getName())
                .append("! You can <a href=\"")
                .append(userService.createLogoutURL(url))
                .append("\">Sign Out</a>.").toString();
            }else{
                message = new StringBuilder()
                .append("Please ")
                .append("<a href=\"")
                .append(userService.createLoginURL(url))
                .append("\">Sign In</a>.").toString();
            }
    
            model.addAttribute("message", message);
    
            return "hello/hello";
        }
    
    }

    The class accepts any request of the pattern /a/hello/* and any request using the GET method will call the hello() method.  Spring allows for controller methods to be very flexible.  hello() takes in the request object (to use to check if the user is logged in) and a model object to return data to the view.  The message created is added to the model map and the name of the view is returned (remember “hello/hello” maps to /WEB-INF/views/hello/hello).

  9. Finally, we are going to set up the “hello/hello” view.  First, we will set up an includes page that sets up the taglibs we will use.  Create the file war/WEB-INF/views/common/includes.jsp with the contents:
    <%@ page session="false"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

    Next,we’ll set up the actual view.  Create the file war/WEB-INF/views/hello/hello.jsp with the contents:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@page isELIgnored="false" %>
    <%@ include file="/WEB-INF/views/common/includes.jsp" %>
    
    <p>${message}</p>
    

    The first line of the jsp sets the contentType and the language of the page.  The next line is needed if you plan to use EL expressions (i.e. ${bean.name}).  Be sure you put isELIgnored, not isElIgnored like the will it play page for GAE has it listed, this took me several hours to figure out. The third line includes the taglibs from the last file we set up.  The final line displays the message attribute that was added to the model in the controller.

You should now be able to click “Debug” and run the application by visiting “localhost:8888/a/hello”.  Next up, I’m going to be adding a tutorial on integrating JDO for GAE’s Datastore into Spring.  If you have any questions or problems with the tutorial, feel free to comment.  I’ll try to get back to them as soon as I can.

References:

Weekend Project

I’ve been working on the Chronism project this week, and this weekend I decided to take a little diversion.  I had been playing around with ajax some for the site’s interface, and so I was starting to some about JSON.  Since I knew I’d have to find a library to do JSON decoding and encoding in Java, and I know some about parsers, so I decided I’d right my own.  JSON is a fairly simple language and I was able to get something up and running fairly quickly.  Working off of a great guide I found for parsing JSON in C#, I wrote a class that takes in a JSON string and builds a HashMap of String Object pairs.

The class doesn’t support JSON arrays yet, and has no error reporting, but I plan to keep developing it, as I would like to have a working library for the Chronism project.  At some point I would also like to extend the functionality to encode a map into JSON as well.

If your interested in the project, I’m releasing it under LGPL and it’s being hosted here.  I’d really appriciate any feedback!

Ant’s SCP Task

Problem: You have an application whose source is going to be distributed with an Ant build script, either internally or publicly and the build script uses the SCP task.  The SCP task is a standard Ant task, ie you don’t have to (can’t) do a <taskdef> to load it’s classes to use it.  The standard Ant distribution, however, does not include the JSch.jar library required by the task.  Normally you would just download the jar and add it to your Ant instance’s /lib directory, however if you are distributing the build file, you cannot expect that everyone will have that included.  This is especially important for those users who just want to type “ant deploy” and have the application up and running.

Solution: The best solution I’ve found for this is to use a custom classloader task, to load the JSch classes before you need the SCP task. JTools’ Classloader task works great for this.  Simply include the JSch library with they libraries for your other custom ant tasks, then in the build file set the SCP task like this:

<taskdef resource="net/jtools/classloadertask/antlib.xml"
        classpathref="${classpath}"/>
<classloader loader="project" classpath="${internal.lib.dir}/js*.jar"/>
<scp file="myfile.txt" todir="user:password@somehost:/home/chuck"/>

This can save those trying to deploy your application a lot of grief for very little overhead.

Starting Work

Chronism Logo

So in my last post I talked about my new project idea to start working on a programming portfolio.  Well the site is going to be a social time tracking application called Chronism.  I’ve gone ahead and bought the domain, and I’m starting to work on some of the basic branding like this fancy logo, and a simple site design.  The reaon I’m not jumping into the coding first is that I’ve got a few days left at my summer internship, and quite frankly I need a diversion that is not Java.  Also, design work is definitely something I could use some practice on.

What I want the point of the application to be, is to encourage users to take ownership of what they are spending their time on, and in doing so, focusing more of their energy on creative pursuit.  The complaints I here about Twitter of the Facebook news feed, is that people generally do not care what you are doing most of the time, but I think most of the people you know will have an interest in what you are working on… what you are making.  To that end, I think a major feature of the site, behind time tracking, should be tie-ins to best of breed services like Flikr, Viemo, and Deviant Art as well as an open api to easily integrate with other services.

If your a student in the Atlanta area and your interested in working on the project, I’d love to take on partners interested in figuring out how to pull a web application together.  Stay tuned for more information about the progress of the site.

The First Project

Last year, I wrote about trying to balance the amount of time you spend consuming and creating on my other blog.  I tried, pretty over ambitiously, to spend a week where I spent as much time creating as I did consuming.  Mostly because I was taking classes at the time and was spending most of my time on that,  but also because I could not track my time very easily,  I didn’t make it very far into the project.  To this end, I’ve decided to make my first project a web app to help you track how long you are productive throughout the day.

The application will be Java based, using the Spring Framework, Hibernate for ORM and either JSP or Velocity for the view formatting, all running in Tomcat.  I want to focus on scalability, security, and solid software practices while getting something up and running as quickly as possible.  I’ve decided to use Java because the product I am working on at work uses a similar architecture, and I would like to understand a Tomcat application from the ground up.

I’ll have more to come soon on my plans for the first two weeks of the project and hopefully a catchy name with a snazzy web 2.0 logo.