Java 8 has reached end of support and will be deprecated on January 31, 2026. After deprecation, you won't be able to deploy Java 8 applications, even if your organization previously used an organization policy to re-enable deployments of legacy runtimes. Your existing Java 8 applications will continue to run and receive traffic after their deprecation date. We recommend that you migrate to the latest supported version of Java.

Accessing Instance Metadata

Google Cloud Platform provides a metadata server that knows details about your App Engine instance, such as its containing project ID, service accounts, and tokens used by the service accounts. You can access this data using simple HTTP requests: no client libraries are required.

This page shows how to access instance metadata from your deployed Java 8 runtime application by making HTTP calls to the appropriate metadata server endpoints.

One useful way to use this API is to get the service account token and supply it as a bearer token in the Authorization header of one of the Google Cloud APIs, to authenticate your application to that particular API service. See the Google Cloud Translation API documentation for an example of how these bearer tokens are used.

Identifying which metadata endpoint to use

The following table lists the endpoints where you can make HTTP requests for specific metadata. The metadata server is accessible at http://metadata.google.internal.

Metadata endpoint Description
/computeMetadata/v1/project/numeric-project-id The project number assigned to your project.
/computeMetadata/v1/project/project-id The project ID assigned to your project.
/computeMetadata/v1/instance/zone The zone the instance is running in.
/computeMetadata/v1/instance/service-accounts/default/aliases
/computeMetadata/v1/instance/service-accounts/default/email The default service account email assigned to your project.
/computeMetadata/v1/instance/service-accounts/default/ Lists all the default service accounts for your project.
/computeMetadata/v1/instance/service-accounts/default/scopes Lists all the supported scopes for the default service accounts.
/computeMetadata/v1/instance/service-accounts/default/token Returns the auth token that can be used to authenticate your application to other Google Cloud APIs.

For example, to retrieve your project ID, send a request to http://metadata.google.internal/computeMetadata/v1/project/project-id.

Making metadata requests

The following sample code gets all of the metadata available for the instance and displays it, except for the service account token.

@SuppressWarnings("serial")
// With @WebServlet annotation the webapp/WEB-INF/web.xml is no longer required.
@WebServlet(name="Metadata",description="Metadata: Write info about GAE Standard",
urlPatterns="/metadata")
publicclass MetadataServletextendsHttpServlet{
privatefinalString[]metaPath={
"/computeMetadata/v1/project/numeric-project-id",// (pending)
"/computeMetadata/v1/project/project-id",
"/computeMetadata/v1/instance/zone",
"/computeMetadata/v1/instance/service-accounts/default/aliases",
"/computeMetadata/v1/instance/service-accounts/default/email",
"/computeMetadata/v1/instance/service-accounts/default/",
"/computeMetadata/v1/instance/service-accounts/default/scopes",
// Tokens work - but are a security risk to display
// "/computeMetadata/v1/instance/service-accounts/default/token"
};
finalString[]metaServiceAcct={
"/computeMetadata/v1/instance/service-accounts/{account}/aliases",
"/computeMetadata/v1/instance/service-accounts/{account}/email",
"/computeMetadata/v1/instance/service-accounts/{account}/scopes",
// Tokens work - but are a security risk to display
// "/computeMetadata/v1/instance/service-accounts/{account}/token"
};
privatefinalStringmetadata="http://metadata.google.internal";
privateTemplateEnginetemplateEngine;
// Use OkHttp from Square as it's quite easy to use for simple fetches.
privatefinalOkHttpClientok=newOkHttpClient.Builder()
.readTimeout(500,TimeUnit.MILLISECONDS)// Don't dawdle
.writeTimeout(500,TimeUnit.MILLISECONDS)
.build();
// Setup to pretty print returned json
privatefinalGsongson=newGsonBuilder()
.setPrettyPrinting()
.create();
privatefinalJsonParserjp=newJsonParser();
// Fetch Metadata
StringfetchMetadata(Stringkey)throwsIOException{
Requestrequest=newRequest.Builder()
.url(metadata+key)
.addHeader("Metadata-Flavor","Google")
.get()
.build();
Responseresponse=ok.newCall(request).execute();
returnresponse.body().string();
}
StringfetchJsonMetadata(Stringprefix)throwsIOException{
Requestrequest=newRequest.Builder()
.url(metadata+prefix)
.addHeader("Metadata-Flavor","Google")
.get()
.build();
Responseresponse=ok.newCall(request).execute();
// Convert json to prety json
returngson.toJson(jp.parse(response.body().string()));
}
@Override
publicvoidinit(){
// Setup ThymeLeaf
ServletContextTemplateResolvertemplateResolver=
newServletContextTemplateResolver(this.getServletContext());
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setCacheTTLMs(Long.valueOf(1200000L));// TTL=20m
// Cache is set to true by default. Set to false if you want templates to
// be automatically updated when modified.
templateResolver.setCacheable(true);
templateEngine=newTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
}
@Override
publicvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsIOException{
StringdefaultServiceAccount="";
WebContextctx=newWebContext(req,resp,getServletContext(),req.getLocale());
resp.setContentType("text/html");
Stringenvironment=
(String)System.getProperties().get("com.google.appengine.runtime.environment");
ctx.setVariable("production",environment);
// The metadata server is only on a production system
if(environment.equals("Production")){
TreeMap<String,String>m=newTreeMap<>();
for(Stringkey:metaPath){
m.put(key,fetchMetadata(key));
if(key.contains("default/email")){
defaultServiceAccount=m.get(key);
}
}
ctx.setVariable("Metadata",m.descendingMap());
m=newTreeMap<>();
for(Stringkey:metaServiceAcct){
// substitute a service account for {account}
key=key.replace("{account}",defaultServiceAccount);
m.put(key,fetchMetadata(key));
}
ctx.setVariable("sam",m.descendingMap());
// Recursivly get all info about service accounts -- Note tokens are leftout by default.
ctx.setVariable("rsa",
fetchJsonMetadata("/computeMetadata/v1/instance/service-accounts/?recursive=true"));
// Recursivly get all data on Metadata server.
ctx.setVariable("ram",fetchJsonMetadata("/?recursive=true"));
}
templateEngine.process("index",ctx,resp.getWriter());
}
}

In the sample code, notice the check to make sure the app is running in production. If the app is running locally, no metadata will be returned from the requests.

Also, notice the use of the Google Gson JSON serializer / deserializer, the OkHttp HTTP and HTTP2 client, and the Thymeleaf templating system. These are not required, but they are useful libraries for your own projects.

Running locally

The metadata server is available for deployed applications: running locally on the development server is not supported. You can add an environment check to your code to expect metadata results only if the app is running in production, as shown in the sample code provided above:

Stringenvironment=
(String)System.getProperties().get("com.google.appengine.runtime.environment");
ctx.setVariable("production",environment);
// The metadata server is only on a production system
if(environment.equals("Production")){
...//show metadata results
}

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025年12月09日 UTC.