Google App Engine

Using Apache Maven

Apache Maven is a software project management and comprehension tool. It is capable of building WAR files for deployment into App Engine. The App Engine team provides both a plugin and Maven Archetypes for the purpose of speeding up development.

A note about Maven projects and Eclipse

A Maven project has a different layout than an Eclipse project. So, if you wish to use a Maven project with Eclipse, you need to do a bit more work. You have the following options:

Maven terms you need to know

During project creation, Maven prompts you to supply groupId, artifactId, version, and the package for the project. What are these in Maven?

Term Meaning
groupId A namespace within Maven to keep track of your artifacts. When people consume your project in their own Maven Project, it will serve as an attribute of the dependency they will end up specifying.
artifactId The name of your project within Maven. It is also specified by consumers of your project when they depend on you in their own Maven projects.
version The initial Maven version you want to have your project generated with. It's a good idea to have version suffixed by -SNAPSHOT because this will provide support in the Maven release plugin for versions that are under development. For more information, see the Maven guide to using the release plugin.
package The Java package created during the generation.

Installing Maven

If you do not already have Maven version 3.1 or greater installed on your system, visit the Apache Maven web site to download and install it.

When Maven is installed and the mvn command is on your command path, you can run the following command to verify that it works, and see which version is installed:

mvn -v

Make sure the version is 3.1 or greater.

Maven App Engine archetypes

Maven Archetypes allow users to create Maven projects using templates that cover common scenarios. App Engine takes advantage of this Maven feature to provide some useful App Engine archetypes at Maven Central. Currently, the App Engine artifacts include:

  • The guestbook-archetype, which you use to generate the guestbook demo sample, complete and ready to run and test in Maven.
  • The skeleton-archetype, which you use to generate a new App Engine project that is ready for your own classes and resources.

Building the guestbook demo using guestbook-archetype

Let's start off using the guestbook archetype to build an immediately runnable demo project.

To create a new Guestbook project:

  1. Change directory to a directory where you want to build the project.

  2. Invoke the following Maven command:

    mvn archetype:generate
    
  3. When prompted to Choose a number or apply filter, supply the value com.google.appengine.archetypes:guestbook-archetype. The archetype will be located and displayed in a short list preceded with a number, for example: 1: remote -> com.google.appengine.archetypes:guestbook-archetype (-)

  4. When you are again prompted to Choose a number or apply filter, supply the number displayed for the artifact in the preceding step, for example, 1.

  5. Select the most recent version from the displayed list of available archetype versions.

  6. When prompted to Define value for property 'groupId', supply the namespace com.google.guestbook.

  7. When prompted to Define value for property 'artifactId', supply the project name guestbook.

  8. When prompted to Define value for property 'version', accept the default value.

  9. When prompted to Define value for property 'package', accept the default value.

  10. When prompted to confirm your choices, accept the default value (Y).

  11. Wait for the project to finish generating. then change directories to the new project directory guestbook.

  12. Build the project by invoking

    mvn clean install
    
  13. Wait for the project to build. When the project successfully finishes you will see a message similar to this one:

    BUILD SUCCESS
     Total time: 10.724s
     Finished at: Thur Jul 04 14:50:06 PST 2013
     Final Memory: 24M/213M
    
  14. Test the application locally in the development server as follows:

    mvn appengine:devserver
    

    Wait for the dev server to start up. When it finishes starting up, you will see a message similar to this one:

     Jul 04, 2013 2:56:42 PM com.google.appengine.tools.development.DevAppServerImpl start
     INFO: The server is running at http://localhost:8080/
     Jul 04, 2013 2:56:42 PM com.google.appengine.tools.development.DevAppServerImpl start
     INFO: The admin console is running at http://localhost:8080/_ah/admin
    
  15. Visit the application at the default URL and port http://localhost:8080/ used by the development server. You will see the guestbook demo app.

  16. To shut down the app and the development server, press Control+C in the Windows/Linux terminal window you started it in, or CMD+C on the Mac.

Creating a new maven App Engine project using skeleton-archetype

The App Engine SDK supplies a maven tool that uses the archetype command to build an empty EAR archive to which you add your own classes and resources.

To create a new App Engine project:

  1. Change to a directory where you want to build your project.

  2. From the command line, invoke Maven as follows:

    mvn archetype:generate
    
  3. When prompted to Choose a number or apply filter, supply the value com.google.appengine.archetypes:skeleton-archetype to display a short list of archetypes matching the filter.

  4. When prompted to Choose a number or apply filter, supply the number displayed for the appengine-skeleton-archetype artifact from the preceding step, for example, 1.

  5. When prompted to Define value for property 'groupId', supply the namespace you want to use for your project, for example, com.mycompany.myapp.

  6. When prompted to Define value for property 'artifactId', supply the project name you want to use; for example, myapp.

  7. When prompted to Define value for property 'version', accept the default value.

  8. When prompted to Define value for property 'package', accept the default value.

  9. When prompted to confirm your choices, accept the default value (Y).

  10. Wait for the project to finish generating. At this point, the basic project layout with required files is complete. Inside the directory where you created the project, you'll have a subdirectory named myapp, which contains a pom.xml file and two subdirectories: myapp-ear and myapp-war, similar to the layout shown here:

    Maven Project Layout

    We'll describe what to do inside these two subdirectories later. (Notice that the location where you'll add your own Java source code is inside myapp-war.)

  11. Change directory to the main app directory, for example, myapp, which contains a pom.xml file and the myapp-ear and myapp-war subdirectories.

  12. Edit pom.xml in myapp so that points to the most recent App Engine SDK version, which currently is 1.9.3:

    <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <appengine.target.version>1.9.3</appengine.target.version>
    </properties>
    

Building using Maven

To build an app created with the skeleton-archetype:

  1. Invoke Maven as follows:

    mvn clean install
    
  2. Wait for the project to build. When the project successfully finishes you will see a message similar to this one:

    BUILD SUCCESS
     Total time: 10.724s
     Finished at: Thur Jul 04 14:50:06 PST 2014
     Final Memory: 24M/213M
    
  3. Optionally, test the application using the following procedure.

Testing your app with the development server

During the development phase, you can run and test your app at any time in the development server by invoking the App Engine Maven plugin.

To test your app:

  1. If you haven't already done so, build your app as described in the previous procedure.

  2. Change directory to the top level of your project's EAR hierarchy (for example, to myapp-ear) and invoke Maven as follows:

    mvn appengine:devserver
    

    Wait for the the server to start. When the server is completely started with your app running, you will see a message similar to this one:

     Jul 04, 2014 2:56:42 PM com.google.appengine.tools.development.DevAppServerImpl start
     INFO: The server is running at http://localhost:8080/
     Jul 04, 2013 2:56:42 PM com.google.appengine.tools.development.DevAppServerImpl start
     INFO: The admin console is running at http://localhost:8080/_ah/admin
    
  3. Use your browser to visit http://localhost:8080/ to access your app.

  4. To shut down the app and the development server, press Control+C in the Windows/Linux terminal window where you started it, or CMD+C on the Mac.

Uploading your app to production App Engine

To upload an app created with the the skeleton-archetype:

  1. Change directory to the top level of your project's EAR hierarchy (for example, to myapp-ear) and invoke Maven as follows:

    mvn appengine:update
    
  2. You will be prompted for an authorization code in the terminal window and your web browser will launch with a consent screen which you must accept in order to be authorized. Follow the prompts to copy any codes from the browser to the command line.

Configuring pom.xml settings for Google App Engine

If you use the App Engine Maven skeleton-archetype to create your project, all of the required pom.xml settings are set for you in your project's main pom.xml file (myapp/pom.xml), although you should specify the latest App Engine SDK version for the <appengine.target.version>.

If you want to use JUnit dependencies (optional), you can do so by setting them in myapp/myapp-war/pom.xml, as follows:

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-all</artifactId>
        <version>1.9.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.google.appengine</groupId>
        <artifactId>appengine-testing</artifactId>
        <version>1.9.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.google.appengine</groupId>
        <artifactId>appengine-api-stubs</artifactId>
        <version>1.9.3</version>
        <scope>test</scope>
    </dependency>

Notice that the scope is set to test):

Adding the App Engine Maven plugin to an existing Maven project

To add the Google App Engine Maven plugin to an existing Maven project, add the following into the plugins section in the project pom.xml file:

<plugin>
   <groupId>com.google.appengine</groupId>
   <artifactId>appengine-maven-plugin</artifactId>
   <version>1.9.3</version>
</plugin>

Specifying a port for local testing

When you run your app in the local development server, the default port is 8080. You can change this default by modifying the plugin entry for appengine-maven-plugin (or adding it if it doesn't exist). For example, we specify port and address in the following <plugin> entry within <plugins> inside the main app directory pom.xml file (myapp/pom.xml):

    <plugin>
         <groupId>com.google.appengine</groupId>
         <artifactId>appengine-maven-plugin</artifactId>
         <version>${appengine.target.version}</version>
         <configuration>
             <enableJarClasses>false</enableJarClasses>
             <port>8181</port>
             <address>0.0.0.0</address>
         </configuration>
    </plugin>

Notice that the <port> sets the port here to 8181 as shown, and the address 0.0.0.0 is specified, which means the development server will listen to requests coming in from the local network.

Managing and running a project with the App Engine Maven plugin

The App Engine Maven plugin enables support for App Engine within Maven. It provides the ability to use the development server and the majority of the functionality of the appcfg tool.

The plugin also provides Google Cloud Endpoints goals for discovery doc generation and client library generation.

Once the App Engine Maven plugin is added to the project's pom.xml file, several App Engine-specific Maven goals are available. To see all of the available goals, invoke the command:

    mvn help:describe -Dplugin=appengine

App Engine Maven plugin goals

The App Engine Maven plugin goals can be categorized as devserver goals, app and project management goals, and Endpoints goals.

Development server goals

These are the development server goals:

appengine:devserver

Runs the App Engine development server. When the server is running, it continuously checks to determine whether appengine-web.xml has changed. If it has, the server does a hot reload of the application. This means that you do not need to stop and restart your application because of changes to appengine-web.xml. The following parameters are available:

  • <fullScanSeconds>
  • <address>
  • <disableUpdateCheck>
  • <jvmFlags>
  • <port>
  • <server>

For example, to enable running the server in debug mode on port 8000 without suspending at start time, you can use the following flags:

<jvmFlags>
  <jvmFlag>-Xdebug</jvmFlag>
  <jvmFlag>-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n</jvmFlag>
</jvmFlags>

By default, the <fullScanSeconds> flag is set to 5 seconds, which means server is checking every 5 seconds for changes in the web application files, and reloads the application automatically. This is useful with IDEs that support the compile on save feature like NetBeans. In order to use this feature, you must configure the <build> section as follows:

<build>
   <outputDirectory>target/${project.artifactId}-${project.version}/WEB-INF/classes</outputDirectory>
   <plugins>
      ....
   </plugins>
</build>
appengine:devserver_start

Performs an asynchronous start for the devserver and then returns to the command line. When this goal runs, the behavior is the same as the devserver goal except that Maven continues processing goals and exits after the server is up and running.

appengine:devserver_stop

Stops the development server. Available only if you started the development server with appengine:devserver_start.

Application management goals

For application and project management, the goals are listed in the following table:

Goal Description
appengine:backends_stop This stops any running development server listening on the port as configured in your pom.xml file. This goal can be used in conjunction with the devserver_start command to do integration tests with the Maven plugin.
appengine:backends_configure Configure the specified backend.
appengine:backends_delete Delete the specified backend.
appengine:backends_rollback Roll back a previously in-progress update.
appengine:backends_start Start the specified backend.
appengine:backends_update Update the specified backend or (if no backend is specified) all backends.
appengine:enhance Runs the App Engine Datanucleus JDO enhancer.
appengine:rollback Rollback an in-progress update.
appengine:set_default_version Set the default application version.
appengine:update Create or update an app version.
appengine:update_cron Update application cron jobs.
appengine:update_dos Update application DoS protection configuration.
appengine:update_indexes Update application indexes.
appengine:update_queues Update application task queue definitions.
appengine:vacuum_indexes Delete unused indexes from application.
Troubleshooting upload errors

If you use the update goal, your update attempt may fail with a message similar to this one: 404 Not Found This application does not exist (app_id=u'your-app-ID'). This error will occur if you have multiple Google accounts and are using the wrong account to perform the update.

To solve this issue, change directories to ~, locate a file named .appcfg_oauth2_tokens_java, and rename it. Then try updating again.

Endpoints goals

These are the Endpoints goals:

appengine:endpoints_get_client_lib

Generate a zip file in the directory ${project.build.directory}/generated-sources/appengine-endpoints/WEB-INF for the Java client library for your endpoints.

appengine:endpoints_get_discovery_doc

A combination of both gen-api-config and gen-discovery-doc commands. The Endpoints API and discovery documents for both REST and RPC are generated in the ${project.build.directory}/generated-sources/appengine-endpoints/WEB-INF directory. The source web.xml is automatically changed with the addition of the Endpoints servlet and the correct Endpoints classes. In order to use the generated artifacts, you need to configure the Maven WAR plugin as follows:

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.3</version>
        <configuration>
          <webXml>${project.build.directory}/generated-sources/appengine-endpoints/WEB-INF/web.xml</webXml>
          <webResources>
            <resource>
              <directory>${project.build.directory}/generated-sources/appengine-endpoints</directory>
              <includes>
                <include>WEB-INF/*.discovery</include>
                <include>WEB-INF/*.api</include>
              </includes>
            </resource>
          </webResources>
        </configuration>
      </plugin>

You can automatically call this goal as part of a Maven build by configuring the App Engine Maven plugin as follows:

    <plugin>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-maven-plugin</artifactId>
            <version>1.9.3</version>
            <configuration>
              <enableJarClasses>false</enableJarClasses>
            </configuration>
            <executions>
              <execution>
                <goals>
                  <goal>endpoints_get_discovery_doc</goal>
                </goals>
              </execution>
            </executions>
          </plugin>

For a reference configuration, see the Endpoint sample application appengine-tictactoe-java-maven.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.