Entorno de ejecución de Java

El entorno de ejecución de Java es la pila de software encargada de instalar el código de tu servicio web y sus dependencias, y de ejecutar el servicio.

Declara el entorno de ejecución de Java para el entorno estándar de App Engine en el archivo app.yaml. Por ejemplo:

runtime: javaVERSION

En el ejemplo anterior, VERSION es el número de versión MAJOR de Java. Por ejemplo, para usar la versión más reciente de Java, Java 21, especifica 21.

Para otras versiones de Java compatibles y la versión de Ubuntu correspondiente para tu versión de Java, consulta el Programa de asistencia del entorno de ejecución.

Antes de comenzar

  1. Descarga la última versión de Google Cloud CLI o actualiza tu gcloud CLI a la versión actual:

    gcloud components update
    
  2. A fin de implementar mediante Maven, deberás agregar el complemento de Maven de App Engine a tu archivo pom.xml:

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

    Entre otras opciones de implementación, se incluye el uso del comando gcloud app deploy o el complemento Gradle de App Engine.

  3. Sigue las instrucciones para que el framework de tu aplicación configure la compilación de un archivo JAR ejecutable.

Compatibilidad con el framework

Con el entorno de ejecución de Java de App Engine, puedes implementar archivos JAR ejecutables. Los entornos de ejecución no incluyen ningún framework de entrega web, lo que significa que no estás limitado a usar bibliotecas o frameworks basados en servlets. Usa tus dependencias nativas o pilas de herramientas de redes, como la biblioteca de Netty.

No estás limitado a estos frameworks y te recomendamos que pruebes el que prefieras, como Grails, Blade, Play!, Vaadin o jHipster.

Implementa proyectos fuente de Maven en el entorno de ejecución de Java

Puedes implementar tu proyecto de Maven como el código fuente y hacer que se compile y se implemente mediante paquetes de compilación de Google Cloud.

Para implementar un proyecto de Maven como el código fuente, ve al directorio de nivel superior de tu proyecto y escribe lo siguiente:

gcloud app deploy pom.xml

Se transmitirán los registros de compilación y de implementación, y podrás ver los registros detallados en la sección historial de Cloud Build en la consola de Google Cloud.

Usa ejecutables de GraalVM

El entorno de ejecución de Java del entorno estándar de App Engine admite ejecutables de imágenes nativas de GraalVM. Una vez que compiles tu app de Java en una imagen nativa de GraalVM, puedes usar la configuración entrypoint en tu archivo app.yaml para que apunte al ejecutable.

Por ejemplo, un ejecutable con el nombre de archivo myexecutable podría tener el siguiente archivo de configuración app.yaml:

runtime: 21 # or another supported runtime version.
entrypoint: ./myexecutable

Las bibliotecas cliente de Google Cloud se pueden usar para compilar aplicaciones como una imagen nativa de GraalVM. Para obtener más información, consulta la documentación sobre cómo compilar imágenes nativas.

Versión de Java

El entorno de ejecución de Java usa la última versión estable de la versión que se especifica en tu archivo app.yaml. App Engine se actualiza de forma automática a las nuevas versiones de actualización de parche, pero no se actualizará automáticamente a las versiones secundarias.

Por ejemplo, tu aplicación podría implementarse en Java 21.0.4 y actualizarse de forma automática a la versión Java 21.0.5 en una implementación posterior de la plataforma administrada, pero no se actualizará a Java 22 de forma automática.

Para aprender a actualizar tu versión de Java, consulta Actualiza una aplicación existente.

El entorno de Open JDK del entorno de ejecución

App Engine ejecuta apps de Java en un contenedor protegido por gVisor en una distribución de Linux de Ubuntu actualizada y su entorno de ejecución compatible openjdk-17-jdk para Java 17 o openjdk-21-jdk para Java 21.

Si deseas obtener versiones de Ubuntu compatibles con tu versión de Java, consulta Programa de asistencia del entorno de ejecución.

App Engine mantiene la imagen base y actualiza el paquete de OpenJDK 17 y OpenJDK 21, sin necesidad de que vuelvas a implementar tu app.

Tu app implementada se ubica en el directorio /workspace del entorno de ejecución. También se puede acceder a ella a través de un vínculo simbólico en /srv.

Versiones de Java de App Engine

Todos los artefactos publicados que empiezan con la versión 2.x.x usan el mecanismo de actualización de código abierto. Consulta el repositorio de GitHub para obtener más detalles.

Dependencias

Para obtener más información sobre la declaración y la administración de dependencias, consulta Especifica dependencias.

Inicio de la aplicación

Los frameworks como Spring Boot, Micronaut y Ktor compilan un uber ejecutable JAR de forma predeterminada. Si tu archivo de compilación de Maven o Gradle genera un Uber JAR ejecutable, el entorno de ejecución inicia la aplicación mediante la ejecución de una aplicación Uber JAR.

Como alternativa, App Engine usará el contenido del campo opcional entrypoint en el archivo app.yaml. Por ejemplo:

runtime: java21 # or another supported runtime
entrypoint: java -Xmx64m -jar YOUR-ARTIFACT.jar

En el ejemplo anterior del jar de la aplicación YOUR-ARTIFACT.jar, se debe cumplir lo siguiente:

  • Estar en el directorio raíz con el archivo app.yaml
  • Contener una entrada Main-Class en el archivo de metadatos META-INF/MANIFEST.MF
  • De manera opcional, contener una entrada Class-Path con una lista de rutas de acceso relativas a otros jar dependientes. Estos se subirán con la aplicación de forma automática.

Para que la app reciba solicitudes HTTP, el punto de entrada debe iniciar un servidor web que escuche en el puerto que especificó la variable de entorno PORT. El entorno de entrega de App Engine configura el valor de la variable de entorno PORT de forma dinámica. Este valor no se puede establecer en la sección env_variables del archivo app.yaml.

Con un punto de entrada personalizado, puedes construir y empaquetar tu aplicación como un archivo JAR delgado que solo contiene el código de la aplicación y las dependencias directas. Cuando implementas la aplicación, el complemento de App Engine solo subirá los archivos que cambiaron, en lugar de todo el paquete Uber JAR.

Asegúrate de usar la variable de entorno PORT

Si ves las advertencias sobre el puerto 8080 y NGINX en los archivos de registro de la app, el servidor web de la app escucha en el puerto 8080 predeterminado. Esto evita que App Engine use su capa NGINX para comprimir las respuestas HTTP. Te recomendamos que configures tu servidor web para que responda a las solicitudes HTTP en el puerto que especificó la variable de entorno PORT, por lo general, 8081. Por ejemplo:

/*
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.appengine;

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!".getBytes();
      t.sendResponseHeaders(200, response.length);
      try (OutputStream os = t.getResponseBody()) {
        os.write(response);
      }
    });

    // Create a second URI path.
    server.createContext("/foo", (var t) -> {
      byte[] response = "Foo!".getBytes();
      t.sendResponseHeaders(200, response.length);
      try (OutputStream os = t.getResponseBody()) {
        os.write(response);
      }
    });

    server.start();
  }
}

Compatibilidad con versiones anteriores de Java

Para conocer las diferencias entre Java 8 y la versión más reciente compatible con Java, consulta Migra desde Java 8 al entorno de ejecución de Java más reciente.

Variables de entorno

El entorno de ejecución configura las siguientes variables del entorno:

Variable de entorno Descripción
GAE_APPLICATION ID de tu aplicación de App Engine. Este ID tiene el prefijo “region code~”, como “e~”, para aplicaciones implementadas en Europa.
GAE_DEPLOYMENT_ID ID de la implementación actual.
GAE_ENV Entorno de App Engine. Se define en standard.
GAE_INSTANCE ID de la instancia en la que se está ejecutando tu servicio.
GAE_MEMORY_MB Cantidad de memoria disponible para el proceso de la aplicación, en MB.
GAE_RUNTIME Entorno de ejecución especificado en el archivo app.yaml.
GAE_SERVICE Nombre de servicio especificado en el archivo app.yaml. Si no se especifica un nombre de servicio, se asigna default.
GAE_VERSION Etiqueta de la versión actual de tu servicio.
GOOGLE_CLOUD_PROJECT ID del proyecto de Google Cloud asociado a tu aplicación.
PORT Puerto que recibe las solicitudes HTTP.
NODE_ENV (solo disponible en el entorno de ejecución de Node.js) Se establece en production cuando se implementa tu servicio.

Puedes definir variables de entorno adicionales en tu archivo app.yaml, pero no es posible anular los valores anteriores, excepto NODE_ENV.

Proxies HTTPS y de reenvío

App Engine finaliza las conexiones HTTPS en el balanceador de cargas y reenvía las solicitudes a tu aplicación. Algunas aplicaciones deben determinar la IP y el protocolo de la solicitud original. La dirección IP del usuario está disponible en el encabezado X-Forwarded-For estándar. Las aplicaciones que necesitan esta información deben configurar sus frameworks web para que confíen en el proxy.

Acceso al sistema de archivos

El entorno de ejecución incluye un directorio /tmp que admite escritura, y todos los demás directorios tienen acceso de solo lectura. Escribir en /tmp ocupa memoria del sistema.

Servidor de metadatos

Cada instancia de tu aplicación puede usar el servidor de metadatos de App Engine para consultar información acerca de la instancia y del proyecto.

Puedes acceder al servidor de metadatos a través de los siguientes extremos:

  • http://metadata
  • http://metadata.google.internal

Las solicitudes enviadas al servidor de metadatos deben incluir el encabezado de solicitud Metadata-Flavor: Google. Este encabezado indica que la solicitud se envió con la intención de recuperar valores de metadatos.

La siguiente tabla enumera los extremos en los que puedes realizar solicitudes HTTP para metadatos específicos:

Extremo de metadatos Descripción
/computeMetadata/v1/project/numeric-project-id El número de proyecto asignado a tu proyecto.
/computeMetadata/v1/project/project-id ID del proyecto asignado a tu proyecto.
/computeMetadata/v1/instance/region La región en la que se está ejecutando la instancia.
/computeMetadata/v1/instance/service-accounts/default/aliases
/computeMetadata/v1/instance/service-accounts/default/email Correo electrónico de la cuenta de servicio predeterminada asignado a tu proyecto.
/computeMetadata/v1/instance/service-accounts/default/ Enumera todas las cuentas de servicio predeterminadas para tu proyecto.
/computeMetadata/v1/instance/service-accounts/default/scopes Enumera todos los alcances compatibles para las cuentas de servicio predeterminadas.
/computeMetadata/v1/instance/service-accounts/default/token Muestra el token de autenticación que puede usarse para autenticar tu aplicación en otras APIs de Google Cloud.

Por ejemplo, para recuperar tu ID del proyecto, envía una solicitud a http://metadata.google.internal/computeMetadata/v1/project/project-id.