The Java 8 runtime

The Java 8 runtime does not include any web-serving framework. The only requirement is that your app should listen and respond on port 8080. The sample code here shows how you can add your own framework, such as Spring Boot, to the Java 8 runtime.

Prerequisites

  • Before you start developing, download the latest version of the Google Cloud CLI or update your gcloud CLI to the current version:

    gcloud components update
    
  • To deploy using maven, you will need to add the App Engine Maven Plugin to your pom.xml:

    <plugin>
       <groupId>com.google.cloud.tools</groupId>
       <artifactId>appengine-maven-plugin</artifactId>
       <version>2.4.4</version>
    </plugin>

    Other options for deploying include using the gcloud app deploy command or the App Engine Gradle plugin.

  • Follow the instructions for your application framework to configure the build of an executable JAR. This executable JAR must run via java -jar app.jar. For example, refer to the Spring Boot documentation.

Organizing your files

Your development file hierarchy should look like this:

MyDir/
  pom.xml
  [index.yaml]
  [cron.yaml]
  [dispatch.yaml]
  src/main/
    appengine/
      app.yaml
    docker/
      Dockerfile
    java/
      com.example.mycode/
        MyCode.java

app.yaml

An app.yaml file is required. Define a file that looks like this:

runtime: java
env: flex

By specifying runtime: java, the runtime image gcr.io/google-appengine/openjdk:8 is automatically selected when you deploy a JAR (*.jar) file.

To select a JDK version, use the runtime_config.jdk field.

runtime: java
env: flex
runtime_config:
  jdk: openjdk8

You can find other app.yaml settings in Using app.yaml.

Optional files

These configuration files are optional:

Place these files at the top level of MyDir. If you use any these files, you must deploy them separately with the gcloud app deploy command.

Default entry point

The entry point for the OpenJDK 8 image is docker-entrypoint.bash, which processes passed command line arguments to look for an executable alternative or arguments to the default command (java).

If the first argument to the image is not an executable, the java command is implicitly added. For example:

$ docker run openjdk -jar /usr/share/someapplication.jar

If the first argument to the image is an executable, such as bash, it will run that command.

For example, you could run a shell with:

> docker run -it --rm openjdk bash
root@c7b35e88ff93:/#

Environment variables

Use the env_variables key in the app.yaml file to set environment variables. For example:

env_variables:
   MY_VAR_COLOR: 'blue'

The following table lists the environment variables that you can use to enable, disable, or configure features.

Env Var Description Type Default
TMPDIR Temporary Directory dirname
JAVA_TMP_OPTS JVM tmpdir args JVM args -Djava.io.tmpdir=${TMPDIR}
GAE_MEMORY_MB Available memory size Set by Google App Engine or /proc/meminfo-400M
HEAP_SIZE_RATIO Memory for the heap percent 80
HEAP_SIZE_MB Available heap size ${HEAP_SIZE_RATIO}% of ${GAE_MEMORY_MB}
JAVA_HEAP_OPTS JVM heap args JVM args -Xms${HEAP_SIZE_MB}M -Xmx${HEAP_SIZE_MB}M
JAVA_GC_OPTS JVM GC args JVM args -XX:+UseG1GC plus configuration
JAVA_USER_OPTS JVM other args JVM args
JAVA_OPTS JVM args JVM args See below
SHUTDOWN_LOGGING_THREAD_DUMP Shutdown thread dump boolean false
SHUTDOWN_LOGGING_HEAP_INFO Shutdown heap info boolean false
SHUTDOWN_LOGGING_SAMPLE_THRESHOLD Shutdown sampling percent 100

If not explicitly set, JAVA_OPTS is defaulted to JAVA_OPTS:=-showversion \ ${JAVA_TMP_OPTS} \ ${DBG_AGENT} \ ${JAVA_HEAP_OPTS} \ ${JAVA_GC_OPTS} \ ${JAVA_USER_OPTS}

The command line executed is effectively (where $@ are the args passed into the docker entry point):

java $JAVA_OPTS "$@"

Local Testing

You can build your app using:

mvn package

And run it using the java command line:

java -jar target/myjar.jar

Or, follow the instructions for you application framework on how to run the app locally.

When you are testing in your local environment, you might prefer to use emulated Google cloud services, rather than remote Google cloud services. There are emulators for Datastore, Pub/Sub, and Bigtable. Use the gcloud command to start them before you run your app:

gcloud beta emulators datastore start
gcloud beta emulators pubsub start
gcloud beta emulators bigtable start

Deploying your app

After completing the configurations, you can use the Google Cloud CLI to deploy this directory containing the app.yaml file and the JAR using:

gcloud app deploy app.yaml

If you are using any of the optional configuration files (index.yaml, cron.yaml, and dispatch.yaml) be sure to deploy them separately with the gcloud command. For example:

gcloud app deploy cron.yaml

Maven

Use Maven to deploy your app:

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.

Gradle

Use Gradle to deploy your app:

gradle appengineDeploy

Customizing the Java 8 runtime

You don't need a Dockerfile to deploy your app into the Java 8 runtime. But, if your app requires additional configuration, you can explicitly provide a Dockerfile to customize the Java runtime.

If you want to use the image as a base for a custom runtime, you can specify runtime: custom in your app.yaml file and then write the Dockerfile like this:

FROM gcr.io/google-appengine/openjdk:8
COPY your-application.jar $APP_DESTINATION

These lines add the JAR in the correct location for the Docker container.

You can add additional directives to the Dockerfile to customize the Java runtime. See Building Custom Runtimes.