Using Apache Maven and the App Engine Plugin (App Engine SDK-based)

This page explains how to manage an App Engine project using Apache Maven, a software project management and comprehension tool. It is capable of building WAR files for deployment into App Engine. Google provides a plugin and Maven Archetypes which are included with Maven 3.5.

When you use Maven, you don't need to manually download the Java libraries from the App Engine SDK. Maven automatically downloads the appropriate libraries when necessary. You can also use Maven to test your app locally and deploy it to production App Engine.

Setting up Maven

Configuring Java

  1. If you don't have Java, download, install and configure it.
  2. Set the compiler flags in the pom.xml to specify Java 7 bytecode or Java 8 byte code. See the appropriate tab below for the settings. Note that the App Engine Java 7 runtime requires Java 7 bytecode.

Installing Maven 3.5

To determine whether Maven is installed and which version you have, invoke the following command:

 mvn -v

If you don't have the proper version of Maven installed:

  1. Download Maven 3.5 from the Maven website.
  2. Install Maven 3.5 on your local machine.

Setting up and validating your Cloud Platform project

You need to set up your Cloud Platform project and install the App Engine SDK:

  1. Use the Google Cloud Platform Console to create and set up your Cloud Platform project:

    Go to App Engine

    1. Select or create a new Cloud Platform project.
    2. If you need to create an App Engine application for your project, you are prompted to select the region where you want your App Engine application located.
    3. The Dashboard opens after your App Engine application has been created in your project.
  2. Install the App Engine SDK for Java and add the directory to your PATH.

Using Maven

Adding the App Engine plugin to an existing project (optional)

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.59</version>
</plugin>

Choosing an archetype

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. Select an App Engine archetype appropriate for your app:

Application Type Artifact Description
Cloud Endpoints API backend hello-endpoints-archetype Generates a simple starter Cloud Endpoints backend API project, ready to build and run.
Cloud Endpoints API backend endpoints-skeleton-archetype Generates a new, empty Cloud Endpoints backend API project ready for your own classes and resources, with required files and directories.

Creating a new project

During project creation, Maven prompts you to supply groupId, artifactId, version, and the package for the project.

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.

This section describes creating a new Cloud Endpoints API v1 backend project. For information on creating an App Engine application using the SDK-based version of the App Engine plugin, see Creating a new project. For information on creating an Endpoints Frameworks v2 application, see Creating a new Endpoints Frameworks app.

To create a Cloud Endpoints backend API project:

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

  2. Invoke the following Maven command:

     mvn archetype:generate -Dappengine-version=1.9.59 -Djava8=false -DCloudSDK_Tooling=false
     -Dfilter=com.google.appengine.archetypes:
    

    where -Dappengine-version is set to the most recent version of the App Engine SDK for Java.

    Set -Djava8=false to deploy the project in the Java 7 runtime.

    Set -DCloudSDK_Tooling=false to use the App Engine SDK for Java tooling.

  3. If you want to create the complete, ready-to-run Hello Endpoints backend API, supply the number corresponding to hello-endpoints-archetype.

    If you want to create an empty project that contains the required directory structure and files, ready for your own classes, supply the number corresponding to endpoints-skeleton-archetype.

  4. When prompted to choose the archetype version, specify the version 1.1.5-1.9.38.

  5. When prompted to Define value for property 'groupId', supply the namespace for your app; for example, com.mycompany.myapp. (For the Hello Endpoints sample backend API, supply the value com.google.appengine.samples.helloendpoints.)

  6. When prompted to Define value for property 'artifactId', supply the project name; for example, myapp. (For the Hello Endpoints sample, supply the value helloendpoints.)

  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. then change directories to the new project directory, for example helloendpoints/.

  11. Build the project by invoking

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

    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 14.846s
    [INFO] Finished at: Tue Jun 03 09:43:09 PDT 2014
    [INFO] Final Memory: 24M/331M
    
  13. If you created the sample Hello Endpoints sample backend API:

    1. Test the application locally in the development server:

      mvn appengine:run
      

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

       [INFO] INFO: Module instance default is running at http://localhost:8080/
       [INFO] Jun 03, 2017 9:44:47 AM com.google.appengine.tools.development.AbstractModule startup
       [INFO] INFO: The admin console is running at http://localhost:8080/_ah/admin
       [INFO] Jun 03, 2017 9:44:47 AM com.google.appengine.tools.development.DevAppServerImpl doStart
       [INFO] INFO: Dev App Server is now running
      
    2. Visit the URL http://localhost:8080 to send requests to the backend API

  14. If you created the Hello Endpoints app:

    1. Familiarize yourself with the basic project layout shown here:

      Maven Project Layout

    2. Add or modify your classes as desired.

Managing a Maven project

Compiling and building your project

To build an app created with the Maven App Engine archetypes:

  1. Change directory to the main directory for your project, for example, guestbook/
  2. Invoke Maven:

    mvn clean package
    
  3. 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 2017
     Final Memory: 24M/213M
    
  4. 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. The procedure varies slightly depending on the artifact used to create the project, so click on the appropriate tab below:

To test your app:

  1. If you haven't already done so, build your app (mvn clean package).

  2. Change directory to your project's main directory /myapp) and invoke Maven:

    mvn appengine:devserver
    

    Wait for 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, 2017 2:56:42 PM com.google.appengine.tools.development.DevAppServerImpl start
    INFO: The server is running at http://localhost:8080/
    Jul 04, 2017 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, or, alternatively, to test the API using the built-in Google API Explorer, visit http://localhost:8080/_ah/api/explorer.

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

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>1.9.59</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.

Deploying your app

See Testing and Deploying an API Backend.

Reference: Available goals

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

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:

<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 Corresponding gcloud Command
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. gcloud app versions start, gcloud app versions stop
appengine:set_default_version Set the default application version. gcloud app services set-traffic
appengine:update Create or update an app version. gcloud app deploy
appengine:update_cron Update application cron jobs. gcloud app deploy
appengine:update_dispatch Update the application dispatch configuration. gcloud app deploy
appengine:update_dos Update application DoS protection configuration. gcloud app deploy
appengine:update_indexes Update application indexes. gcloud datastore create-indexes [INDEX_YAML]
appengine:update_queues Update application task queue definitions. gcloud app deploy
appengine:vacuum_indexes Delete unused indexes from application. gcloud datastore cleanup-indexes [INDEX_YAML]
appengine:start_module_version Start the specified module version. gcloud app versions start
appengine:stop_module_version Stop the specified module version. gcloud app versions stop

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.

Cloud 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:

<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:

<plugin>
  <groupId>com.google.appengine</groupId>
  <artifactId>appengine-maven-plugin</artifactId>
  <version>1.9.59</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.

Send feedback about...

Cloud Endpoints Frameworks for App Engine