Note: Services were previously called "modules", and services are still declared in
appengine-web.xml files as modules, for example:
appengine-web.xmlfile, you are selecting a compat Java8 runtime that supports some of the App Engine service APIs. You must provide an exploded WAR directory containing the
appengine-web.xmlfile and also a
web.xmlfile. See The Java 8 / Jetty 9.3 Compat Runtime for more details. Using Maven or Gradle will make this easier.
An App Engine Java app must have a file named
appengine-web.xml in its WAR, in the directory
WEB-INF/. This is an XML file whose root element is
<appengine-web-app>. A minimal file that specifies
<vm>true</vm>, the runtime, if the app is threadsafe, with no static files or resource files looks like this:
<?xml version="1.0" encoding="utf-8"?> <appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <vm>true</vm> <threadsafe>true</threadsafe> </appengine-web-app>
The XML Schema Definition of
appengine-web.xml can be found here. The raw XSD file can be downloaded from this link.
You can find the DTD and schema specifications for this file in the SDK's
When you deploy a Java application in the flexible environment, it runs in Java 7, with Jetty 9 and Servlet 3.1.
Java applications are deployed using a WAR directory. The directory must
web.xml file and an
To select the flexible environment, you must include the
vm setting in
||Select the flexible environment by specifying "true"|
||Tells App Engine that your application can handle multiple requests simultaneously.
If false, App Engine sends requests serially to a given webserver. If you wish to use concurrent
requests, make sure that your application uses proper thread synchronization before
The flexible runtime environment
There are separate sections in the configuration file for specifying network settings, compute resources, and health checking behavior:
<network> <forwarded-port>8081</forwarded-port> <forwarded-port>8082:8083</forwarded-port> <instance-tag>"tag_name"</instance-tag> <name>"network_name"</name> </network>
||Ports can be forwarded from the VM to your application's container. You can specify that a port forwards to the same port number (8081), or from one port to another (8082:8083). Port 8080 is forwarded by default.|
||A tag with that name is assigned to each instance of the service when it is created. Tags can be useful in
||Every VM instance is assigned to a Compute Engine network. when it is created. Use this setting to specify a network name. Give the short name, not the resource path (for example "default" rather than "https://www.googleapis.com/compute/v1/projects/my-project/global/networks/default"). If you do not specify a network name, VMs are assigned to the project's default network (which has the name "default").|
These settings control the computing resources. App Engine assigns a machine type based on the amount of CPU and memory you've specified. The machine is guaranteed to have at least the level of resources you've specified, it might have more.
||The number of cores; it can be a fraction less than one.||.5 cores|
||RAM, in GB||1.3 GB|
||Size in GB. The minimum is 10GB and maximum is 10240GB.||10GB|
Periodic health check requests are used to confirm that a VM instance has been successfully deployed, and to check that a running instance maintains a healthy status. Each health check must be answered within a specified time interval. An instance is unhealthy when it fails to respond to a specified number of consecutive health check requests. An unhealthy instance will not receive any client requests, but health checks will still be sent. If an unhealthy instance continues to fail to respond to a predetermined number of consecutive health checks, it will be restarted.
Health check requests are enabled by default, with default threshold values. You can customize VM health checking by adding an optional health check section to your configuration file:
||Enable/disable health checks. Health checks are enabled by default.
To disable health checking, set to
||Time interval between checks||5 seconds|
||Health check timeout interval||4 seconds|
||An instance is unhealthy after failing this number of consecutive checks||2 checks|
||An unhealthy instance becomes healthy again after successfully
responding to this number of consecutive checks
||The number of consecutive check failures that will trigger a VM restart||60 checks|
Servlet 3.1 Annotations Processing
Jetty 9 Quickstart works with advanced servlet annotations to improve startup performance.
If you are using the Servlet 3.1 specification, and you want the Servlet 3.1
annotations to be processed, include this beta setting in your
<beta-settings> <setting name="java_quickstart" value="true" /> </beta-settings>
This will cause the app to be scanned for annotations while it is being deployed or run locally,
with the result being the same as if the equivalent elements had been included in the
Service scaling settings
The keys used to control scaling of a service depend on the type of scaling you assign to a service:
If you do not specify any scaling, then automatic scaling is selected by default.
<manual-scaling> <instances>5</instances> </manual-scaling>
<automatic-scaling> <min-num-instances>5</min-num-instances> <max-num-instances>20</max-num-instances> <cool-down-period-sec>120</cool-down-period-sec> <cpu-utilization>0.5</cpu-utilization> </automatic-scaling>
||Required to enable manual scaling for a service.|
||The number of instances to assign to the service at the start. This number
can later be altered by using the
Modules API |
When you use automatic scaling you must specify the minimum and maximum number of instances. The other settings are optional.
||Automatic scaling is assumed by default. Include this line if you are going to specify any of the automatic scaling settings.|
||Default: 20. Specifies the maximum number of instances that each version of your app can scale up to. The maximum number of instances in your project is limited by your project's resource quota.|
||The time interval between auto scaling checks. The cool-down period must be greater than or equal to 60 seconds. The default is 120 seconds.|
||This header is required if you are going to specify the target CPU utilization.|
||Target CPU utilization (default 0.5). CPU use is averaged across all running instances and is used to decide when to reduce or increase the number of instances.|
By default, any user can access any URL using either HTTP or HTTPS. If you want to disallow the use of HTTPS for the application, put the following in the
There is no way to disallow HTTPS for some URL paths and not others in the Java runtime environment.
Defining environment variables
You can define system properties and environment variables that are set when the application is running.
<system-properties> <property name="myapp.maximum-message-length" value="140" /> <property name="myapp.notify-every-n-signups" value="1000" /> <property name="myapp.notify-url" value="http://www.example.com/signupnotify" /> </system-properties> <env-variables> <env-var name="DEFAULT_ENCODING" value="UTF-8" /> </env-variables>
Enabling servlet sessions
(Only available when using "compat" runtimes)
App Engine includes an implementation of sessions, using the servlet session interface. The implementation stores session data in the App Engine datastore for persistence, and also uses memcache for speed. As with most other servlet containers, the session attributes that are set with
session.setAttribute() during the request are persisted at the end of the request.
This feature is off by default. To turn it on, add the following to
The implementation creates datastore entities of the kind
_ah_SESSION, and memcache entries using keys with a prefix of
It's possible to reduce request latency by configuring your application to asynchronously write HTTP session data to the datastore:
<async-session-persistence enabled="true" />
With async session persistence turned on, App Engine will submit a Task Queue task to write session data to the datastore before writing the data to memcache. By default the task will be submitted to the
default queue. If you'd like to use a different queue, add the
<async-session-persistence enabled="true" queue-name="myqueue"/>