Re-packaging a WAR file into a JAR file

If you are migrating to the latest supported Java version and your app does not use legacy bundled services, you must re-package your App Engine Java 8 web application into an executable JAR file.

Your application must have a Main class that starts a web server that responds to HTTP requests on port 8080, which might be specified by the PORT environment variable.

For example:

import com.sun.net.httpserver.HttpServer; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; public class Main {  public static void main(String[] args) throws IOException {  // Create an instance of HttpServer bound to port defined by the   // PORT environment variable when present, otherwise on 8080.  int port = Integer.parseInt(System.getenv().getOrDefault("PORT", "8080"));  HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);  // Set root URI path.  server.createContext("/", (var t) -> {  byte[] response = "Hello World from Google App Engine Java 11.".getBytes();  t.sendResponseHeaders(200, response.length);  try (OutputStream os = t.getResponseBody()) {  os.write(response);  }  });  // Start the server.  server.start();  } }

WAR migration example (Java 11)

The following instructions demonstrate how to repackage an App Engine Java 8 hello-world application as a JAR to run on the Java 11 runtime.

The migration uses the appengine-simple-jetty-main artifact. This provides a Main class with a simple Jetty web server that loads a WAR file and packages your app into an executable JAR file:

  1. Clone the Embedded Jetty Server artifact to your local machine:

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples 

    Alternatively, you can download the sample as a zip file and extract it.

  2. Change to the directory that contains the sample code:

    cd java-docs-samples/appengine-java11/appengine-simple-jetty-main/ 
  3. Install the dependency locally:

    mvn install 
  4. Add the following code to your project pom.xml file:

    • appengine-simple-jetty-main dependency:
      <dependency>  <groupId>com.example.appengine</groupId>  <artifactId>simple-jetty-main</artifactId>  <version>1</version>  <scope>provided</scope> </dependency>
    • maven-dependency plugin:
      <plugin>  <groupId>org.apache.maven.plugins</groupId>  <artifactId>maven-dependency-plugin</artifactId>  <version>3.6.1</version>  <executions>  <execution>  <id>copy</id>  <phase>prepare-package</phase>  <goals>  <goal>copy-dependencies</goal>  </goals>  <configuration>  <outputDirectory>  ${project.build.directory}/appengine-staging  </outputDirectory>  </configuration>  </execution>  </executions> </plugin>
      App Engine deploys files located in the ${build.directory}/appengine-staging directory. By adding the maven-dependency plugin to your build, App Engine installs your specified dependencies to the correct folder.
  5. Create an entrypoint element in your app.yaml file to call the appengine-simple-jetty-main object and pass your WAR file as an argument. For example, see the helloworld-servlet sample app.yaml file:

    runtime: java11 entrypoint: 'java -cp "*" com.example.appengine.jetty.Main helloworld.war'
  6. To run your application locally:

    1. Package your application:

      mvn clean package 
    2. Start the server with your WAR file as an argument.

      For example, you can start the server in the helloworld-servlet sample by running the following command from your java-docs-samples/appengine-java11/appengine-simple-jetty-main/ folder:

      mvn exec:java -Dexec.args="../helloworld-java8/target/helloworld.war" 
    3. In your web browser, enter the following address:

      http://localhost:8080

  7. To deploy your application:

    gcloud tooling

    gcloud app deploy

    Maven plugin

    mvn package appengine:deploy -Dapp.deploy.projectId=PROJECT_ID

    Replace PROJECT_ID with the ID of your Google Cloud project. If your pom.xml file already specifies your project ID , you don't need to include the -Dapp.deploy.projectId property in the command you run.