This page describes how to install and use the bundled services with the latest supported Java version for the App Engine standard environment. Your app can access the bundled services through the App Engine API JAR.
Before you begin
Refer to the list of legacy bundled services APIs you can call in the latest supported Java version.
This page requires that your app is running a supported Java version. To migrate your app from the first-generation to the second-generation runtime, see Migrate from Java 8 to the latest Java runtime and the migration considerations section.
If you use legacy bundled services and want to upgrade to Java 21, see Upgrade an existing application to learn more about your configuration options.
Install the App Engine API JAR
To use legacy bundled services in your latest supported Java app, you must
use an appengine-web.xml
file to configure your app (instead of an app.yaml
file).
The following example demonstrates how to add configuration settings in your
appengine-web.xml
for version 21 and later on EE10 (default), version
21 on EE8, and version 17 and earlier. To use the latest supported version on
the default configuration, you must update your application servlets and
dependencies to include the Jakarta
namespace. To learn more about your configuration options,
see Upgrade an existing application.
Add the following settings in your appengine-web.xml
file depending on the Java version:
v21 and later (EE10)
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<runtime>java21</runtime> <!-- or another supported version -->
<app-engine-apis>true</app-engine-apis>
</appengine-web-app>
v21 (EE8)
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<runtime>java21</runtime>
<system-properties> <!-- run your apps on EE8 -->
<property name="appengine.use.EE8" value="true"/>
</system-properties>
<app-engine-apis>true</app-engine-apis>
</appengine-web-app>
v17 and earlier
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<runtime>java17</runtime> <!-- or another supported version -->
<app-engine-apis>true</app-engine-apis>
</appengine-web-app>
To specify the legacy bundled services as a dependency, add the following
lines in your pom.xml
file:
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>2.0.31</version> <!-- or later-->
</dependency>
If your app uses a web.xml
file, you must add the <app-engine-apis>
element
and set it to true
:
<app-engine-apis>true</app-engine-apis>
To deploy your Java 21 app, run the
mvn appengine:deploy
command, or the
gcloud app deploy ~/my_app/WEB-INF/appengine-web.xml
command on a compiled and staged web application.
Default entrypoint used by Java 21
Java 21 apps can benefit from extra user configuration when starting the JVM for web apps.
The default entrypoint used to boot the JVM is generated by App Engine buildpacks.
Essentially, it is equivalent to define this entrypoint in the appengine-web.xml
file. For example:
java --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio.charset=ALL-UNNAMED -showversion -Xms32M -Xmx204M -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+PrintCommandLineFlags -Dclasspath.runtimebase=/base/java_runtime -Djava.class.path=/base/java_runtime/runtime-main.jar -Djava.library.path=/base/java_runtime: com/google/apphosting/runtime/JavaRuntimeMainWithDefaults --fixed_application_path=/workspace /base/java_runtime
We don't recommend changing this default entrypoint as the memory settings are calculated based on the instance type (F1, F2, F4) and memory available.
By default, we use --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio.charset=ALL-UNNAMED
to open some necessary JDK APIs.
Entry Point Features
The entry point for the second-generation
Java versions can be customized with user-defined environment
variables added in the appengine-web.xml
configuration file.
The following table indicates the environment variables that can be used to enable/disable/configure features, and the default values if they are not set:
Env Var | Description | Type | Default |
---|---|---|---|
CPROF_ENABLE |
Stackdriver Profiler | boolean | false |
GAE_MEMORY_MB |
Available memory | size | Set by 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 |
If not explicitly set, JAVA_OPTS
is defaulted to:
JAVA_OPTS:=-showversion \
$JAVA_HEAP_OPTS \
$JAVA_GC_OPTS \
$JAVA_USER_OPTS
When CPROF_ENABLE
is true, the default entrypoint adds the PROFILER_AGENT
as:
-agentpath:/opt/cprof/profiler_java_agent.so=--logtostderr
For example, if your application code needs more -add-opens
flags, you can use the JAVA_USER_OPTS
environment variable defined in the appengine-web.xml
file:
<env-variables>
<env-var name="JAVA_USER_OPTS" value="--add-opens java.base/java.util=ALL-UNNAMED" />
</env-variables>
Migration considerations
You should be aware of the following considerations if you are migrating to a second-generation Java runtime and your app uses legacy bundled services:
- To test the legacy bundled services capabilities in your second-generation Java app, you can use the local development server.
- Unlike the Java 8 runtime, the second-generation Java runtimes
include JVM as part of the instance memory. If you see memory-related errors in the logs, consider
increasing the instance class size in your
appengine-web.xml
file. - If your application is trying to call an API which is not
enabled for the second-generation Java runtimes, it will receive a
com.google.apphosting.api.ApiProxy$FeatureNotEnabledException
error. - All apps are assumed to be thread safe in the second-generation Java
runtimes. You must remove the
threadsafe
element in yourapp.yaml
orappengine-web.xml
file when Migrate from Java 8 to the latest Java runtime.
Example (Datastore)
For an example of how to use Firestore in Datastore mode (Datastore), see the legacy bundled services for Java 11 code sample in GitHub.