Migrating to the Cloud SDK-based Maven plugin

If you are using the Java App Engine SDK-based plugin (com.google.appengine.appengine-maven) and want to move to the new Cloud SDK, migrate to the Cloud SDK-based (com.google.cloud.tools.appengine-maven) plugin.

Benefits of the Cloud SDK-based plugin

Upgrading to the new plugin provides the following benefits:

  • Uses the same authentication credentials as all other Cloud SDK -based commands, which are produced from the standard gcloud auth login flow.

  • Supports the App Engine flexible environment.

  • Updates the local development server automatically as part of the standard Cloud SDK update flow.

  • Supports deploying App Engine service (cron, queues, dos, dispatch) configurations, independently from your service.

Notable differences

Before you migrate, be aware of these notable differences:

Cloud SDK dependency
The old plugin runs without any specific local environment dependencies, besides Java, but the new plugin requires that you have the Cloud SDK installed.
No Endpoints discovery doc generation
The new plugin does not generate Endpoints discovery docs, a feature available in a separate plugin. Running your Endpoints backend no longer requires generating this file in a build step as the server now generates it at runtime. You should use the new plugin only if you need to generate client libraries such as for iOS or Android. Learn more about the new plugins by reviewing the Migrating to Endpoints Frameworks for App Engine guide.
EAR file format no longer supported
The new plugin no longer supports the EAR file format for running and deploying multiple services at the same time.
New deployment command
The old plugin calls the appcfg command to deploy applications, while the new plugin deploys using the new gcloud CLI.
JPA/JDO Datanucleus enhancement tasks are no longer included
The new plugin does not support Datanucleus enhancement of any type. If your project uses the Datanucleus JDO or JPA enhancement support from the old plugin, you must configure the 3rd party Datanucleus (JDO instructions, JPA instructions), Maven plugin separately when you migrate.

Use of YAML configuration files is supported, but not XML.

Migrating to the new plugin

To migrate to the new plugin, do the following:

  1. Add the Cloud SDK-based plugin to your pom.xml file.

    <build>
        <plugins>
           [...]
              <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>appengine-maven-plugin</artifactId>
                <version>2.2.0</version>
                <configuration>
                    <projectId>your-project-ID-goes-here</projectId>
                    <version>1</version>
                </configuration>
            </plugin>
           [...]
        </plugins>
    </build>
    
  2. Specify your target Google Cloud project ID and the service and version in the plugin configuration. The new tooling ignores the application and version elements in your appengine-web.xml file.

  3. Test your new config by running and deploying your application as follows:

    1. Run the app using the plugin's fully qualified name:

        mvn com.google.cloud.tools:appengine-maven-plugin:run
      
    2. Deploy the app using the plugin's fully qualified name:

        mvn com.google.cloud.tools:appengine-maven-plugin:deploy
      

      Be sure to namespace the plugin goal invocation if you still have the old appengine plugin in your pom.xml.

If you have a more customized configuration, you should find equivalent staging, local run, and deployment flags in the new plugin.

After verifying that everything is working as expected, remove the com.google.appengine appengine-maven-plugin from your pom.xml and the application and version elements from your appengine-web.xml file.

You can now invoke your new plugin's goals using the shortened notation:

mvn package appengine:deploy

Migrating EAR-based multi-service configurations

With the new plugin, you don't aggregate your services in an EAR package. Instead, when you want to test your services locally, you can run each service individually or take a few extra steps to run multiple services with just a single command. When you are ready to deploy your services, you can deploy them individually, or depending on how you have organized your project, you can deploy all services with a single command.

To run multiple services locally, update the the appengine-maven-plugin with the list of services you want to run. If your services share a parent POM, you can add this list the appengine-maven-plugin in the parent POM. Otherwise, add the list to the appengine-maven-plugin in the POM of the default service.

To add the list of services to the appengine-maven-plugin:

  1. For every context-root in the application.xml of your EAR package, add a service element to the appengine-maven-plugin.

    In each service element, specify the target subdirectory that contains the service's exploded WAR.

    For example:

    <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>appengine-maven-plugin</artifactId>
        <version>2.2.0</version>
        <configuration>
            <deploy.projectId>your-project-name</deploy.projectId>
            <deploy.version>your-project-version</deploy.version>
            <services>
                <!-- for each service in your EARs application.xml -->
                <service>
                    ${project.parent.basedir}/service-name/target/service-name-${project.version}
                </service>
                <service>
                    ${project.parent.basedir}/another-service/target/another-service-${project.version}
                </service>
            </services>
        </configuration>
    </plugin>
    

    If your directory structure looks like this:

     ~/my-ear/default-service/
     ~/my-ear/another-service/
    

    Then the pathnames in the service elements need to render as follows:

     <service>~/my-ear/default-service/target/default-service-1.0-SNAPSHOT</service>
     <service>~/my-ear/another-service/target/another-service-1.0-SNAPSHOT</service>
    
  2. Confirm your new config works by running the following command from your default service directory:

    mvn package appengine:run
    
  3. After verifying that your default service is running all the services locally, completely remove your EAR package.

If the root directory of your project contains only your services, you can deploy all of those services with one mvn appengine:deploy command. You must first add the appengine-maven-plugin to your parent pom.xml file. When you run mvn appengine:deploy, the command iterates through each of your project's services to locate their configuration files and then deploy each service.

App Engine SDK-based vs Cloud SDK-based Maven commands

The following table shows the different ways you invoke the Maven plugin, depending on whether you use the App Engine SDK-based Maven plugin or the Cloud SDK-based Maven plugin.

Action App Engine SDK-based Cloud SDK-based
Run the app locally appengine:devserver appengine:run
Deploy a new app, version, or service. appengine:update appengine:deploy or appengine:deployAll
Set the default application version. appengine:set_default_version gcloud app services set-traffic or gcloud app versions migrate
Update application cron jobs. appengine:update_cron appengine:deployCron
Update the application dispatch configuration. appengine:update_dispatch appengine:deployDispatch
Update application DoS protection configuration. appengine:update_dos appengine:deployDos
Update application task queue definitions. appengine:update_queues appengine:deployQueue
Update Datastore Indexes. appengine:update_indexes appengine:deployIndex
Delete unused indexes from application. appengine:vacuum_indexes gcloud datastore cleanup-indexes
Start the specified version. appengine:start_module_version gcloud app versions start
Stop the specified version. appengine:stop_module_version gcloud app versions stop
Rollback an in-progress update. appengine:rollback
Note that you can also migrate traffic back to an older version
gcloud app versions start, gcloud app versions stop, or use gcloud app services set-traffic) to migrate back to an older version.