tisdag 15 januari 2013

GAE - Getting started with Google App Engine using Maven.

In this post we will be looking into how one can use Maven to build and run a GAE locally. We will create a super simple web application. However the aim of this post is to document the steps one need to perform to be able to run a simple application on Google App Engine.

If you just like to get a the complete project follow this link: http://files.loop81.com/files/rest/download/92a771ad-7aef-43bc-9438-ffc70a358874

I assume that you have Maven installed, and have a configured command-line where you is able to execute Maven.

First we need to setup our project. Since we are building a web-application let us create a empty web-app using Mavens archetypes. User your favorite command-line or IDE if you like. I will be using Cygwin, see http://loop81.blogspot.se/2012/12/os-setting-up-cygwin.html if you like to know how my Cygwin is configured.

Execute the following in a folder where you like to have your source code stored:

mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.loop81.gae -DartifactId=test-app -Dfilter=org.apache.maven.archetypes:maven-archetype-webapp

This will start a interactive session where we will configure our project. Answer the questions, often the default values are enough. I choose to call my application com.loop81.gae.test-app as you see defined in the DgroupId and DartifactId. When you have run this command you should have a project created for you witha pom.xml and some source folders.

Quite boring so far. Let us get on with the GAE stuff and make some cool things. Bellow is a complete pom.xml which enables GAE for us.
<project 
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.loop81.gae</groupId>
  <artifactId>test-app</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>

  <name>test-app Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <gae.version>1.7.4</gae.version>
    <gae.home>${settings.localRepository}/com/google/appengine/appengine-java-sdk/${gae.version}/appengine-java-sdk-${gae.version}</gae.home>
  </properties>
  
  <dependencies>      
    <dependency>
      <groupId>com.google.appengine</groupId>
      <artifactId>appengine-api-1.0-sdk</artifactId>
      <version>${gae.version}</version>
    </dependency>
  </dependencies>
  
  <build>
    <finalName>test-app</finalName>
    
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.5.1</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
      
      <plugin>  
        <groupId>net.kindleit</groupId>  
        <artifactId>maven-gae-plugin</artifactId>  
        <version>0.9.4</version>  
        <configuration>
          <unpackVersion>${gae.version}</unpackVersion>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
Line 18: Here we use a property to specify the version of the GAE API, which we will be using. The reason for this is that we will be using the version of the API at many places in the pom-file.

Line 19: This defines the home of the binaries which the maven-gae-plugin will use to start a local app engine. The property point out the location of your Maven-repository and the actual location on the disk of the binaries.

Line 21-26: Define the dependency to the GAE API. Note: the usage of the gae.version property.

Line 43-50: The above has actually been quite basic and this is the real magic. The maven-gae-plugin is a nice plugin which gives you the ability to start and stop a local app engine instance. The plugin require that you have created a property pointing to the GAE binaries as we defined on line 19. You can find some more information about the plugin at http://www.kindleit.net/maven_gae_plugin/. However the information about the plugin is a bit bad so see further down in this post for some other helpful information about the plugin.

Before we try out our application for the first time we need one more thing. To be able to run the application in the app engine we need to tell the engine that this is a valid app engine application. This is done by adding a configuration file in the WEB-INF folder. Add the following file in /test-app/src/main/webapp/WEB-INF and name it appengine-web.xml.
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
  <application>noteit-loop81</application>
  <version>1</version>
  <threadsafe>true</threadsafe>
</appengine-web-app>
For more information about the configuration see: https://developers.google.com/appengine/docs/java/config/appconfig

Now we are ready to test the application for the first time. Since we used Maven to create a web-app for us there is a simple JSP page in /test-app/src/main/webapp saying hello to the world. However before we can start the app engine we need to prepare some files.

  1. Run gae:unpack to have the plugin unpacking the files required to start the app engine. The files unpackaed are stored in you maven repository at com\google\appengine\appengine-java-sdk\1.7.4\appengine-java-sdk-1.7.4.
  2. Now it is time to start the app engine for the first time, but first run mvn package to build you application. If you miss this step you will get a message saying "Unable to find the webapp directory".
  3. Type gae:start to start the application. If everything starts as expected you should get a "Build success".
  4. Browse in on localhost:8080 and the famous "Hello world" text will be there for you.

If you for some reason run into this exception when trying to start the app engine.

Exception in thread "main" java.lang.RuntimeException: java.net.BindException: Address already in use: JVM_Bind
        at net.kindleit.gae.runner.AppEnginePluginMonitor.main(AppEnginePluginMonitor.java:139)
Caused by: java.net.BindException: Address already in use: JVM_Bind
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:383)
        at java.net.ServerSocket.bind(ServerSocket.java:328)
        at java.net.ServerSocket.<init>(ServerSocket.java:194)
        at net.kindleit.gae.runner.AppEnginePluginMonitor.<init>(AppEnginePluginMonitor.java:56)
        at net.kindleit.gae.runner.AppEnginePluginMonitor.main(AppEnginePluginMonitor.java:133)

You already have started a local app engine. Run mvn gae:stop to stop the old one first.

So this was our first step towards developing on Google App Engine, quite simple since most of the parts are about getting the maven-gae-plugin configured and working. However we will end this post describing a useful thing with Maven. Type mvn help:describe -Dplugin=net.kindleit:maven-gae-plugin -Ddetail in your console and you will be presented with a list of all goals of the maven-gae-plugin together with all configurable parameters. So now you never have to Google if you do not understand a plugin :)

For a complete project follow this link: http://files.loop81.com/files/rest/download/92a771ad-7aef-43bc-9438-ffc70a358874

Inga kommentarer:

Skicka en kommentar