Ambiente de execução do Java

O ambiente de execução do Java é a pilha de software responsável por instalar o código do serviço da Web e as dependências dele, além de executar o serviço.

Declare o ambiente de execução Java para o ambiente padrão do App Engine no arquivo app.yaml. Por exemplo:

runtime: javaVERSION

Em que VERSION é o número de versão MAJOR do Java. Por exemplo, para usar a versão mais recente do Java, Java 21, especifique 21.

Para outras versões do Java com suporte e a versão do Ubuntu correspondente à sua versão do Java, consulte a Programação de suporte do ambiente de execução.

Antes de começar

  1. Faça o download da versão mais recente da Google Cloud CLI ou atualize a CLI gcloud para a versão atual:

    gcloud components update
    
  2. Para implantar usando o Maven, você precisará adicionar o Plug-in do Maven para o App Engine ao arquivo pom.xml:

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

    Outras opções de implantação incluem o uso do comando gcloud app deploy ou do plug-in do Gradle para o App Engine.

  3. Siga as instruções do framework do seu aplicativo para configurar o build de um arquivo JAR executável.

Compatibilidade do framework

Com o ambiente de execução do Java para o App Engine, é possível implantar arquivos JAR executáveis. Os ambientes de execução não inclui nenhum framework de exibição na Web, o que significa que você não está limitado a usar bibliotecas ou frameworks baseados em servlet. Use suas dependências nativas ou pilhas de rede, como a biblioteca Netty (em inglês).

Você não precisa usar apenas esses frameworks. Recomendamos que você teste outras opções, como Grail, Blade, Pixel, Play!, Vaadin ou jHipster (em inglês).

Implantar projetos de origem do Maven no ambiente de execução do Java

É possível implantar o projeto do Maven como código-fonte, além de criá-lo e implantá-lo usando os buildpacks do Google Cloud.

Para implantar um projeto do Maven como código-fonte, acesse o diretório de nível superior do projeto e digite:

gcloud app deploy pom.xml

Os registros de criação e implantação serão transmitidos, e você poderá conferir os registros detalhados na seção de histórico do Cloud Build no console do Google Cloud.

Como usar executáveis do GraalVM

O ambiente de execução do Java do ambiente padrão do App Engine é compatível com executáveis de imagens nativas do GraalVM. Depois de compilar o aplicativo Java usando uma imagem nativa do GraalVM, use a configuração entrypoint no arquivo app.yaml para apontar para o executável.

Por exemplo, um executável com o nome de arquivo myexecutable pode ter o seguinte arquivo de configuração app.yaml:

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

As bibliotecas de cliente do Google Cloud podem ser usadas para compilar aplicativos como uma imagem nativa do GraalVM. Para mais informações, consulte a documentação sobre como compilar imagens nativas.

Versão do Java

O ambiente de execução usa a versão estável mais recente da versão especificada em seu arquivo app.yaml. O App Engine é atualizado automaticamente para novas versões de patch, mas não atualiza automaticamente a versão secundária.

Por exemplo, seu aplicativo pode ser implantado no Java 21.0.4 e atualizado automaticamente para a versão Java 21.0.5 em uma implantação posterior da plataforma gerenciada, mas não será atualizado automaticamente para Java 22.

Para saber como fazer upgrade da versão do Java, consulte Fazer upgrade de um aplicativo atual.

O ambiente Open JDK do ambiente de execução

O App Engine executa apps Java em um contêiner protegido pelo gVisor em uma distribuição do Linux Ubuntu atualizada e no ambiente de execução openjdk-17-jdk para Java 17 ou openjdk-21-jdk para Java 21.

Para versões do Ubuntu compatíveis com sua versão do Java, consulte Programação de suporte ao ambiente de execução.

O App Engine mantém a imagem base e atualiza o pacote OpenJDK 17 e OpenJDK 21 sem exigir que você reimplante o aplicativo.

O app implantado está localizado no diretório /workspace do ambiente de execução. Ele também pode ser acessado por meio de um link simbólico em /srv.

Versões do Java do App Engine

Todos os artefatos lançados que começam com a versão 2.x.x usam o mecanismo de lançamento de código aberto. Consulte o repositório do GitHub para mais detalhes.

Dependências

Para conferir mais informações sobre como declarar e gerenciar dependências, consulte Como especificar dependências.

Inicialização do aplicativo

Frameworks, como Spring Boot, Micronaut e Ktor, criam um JAR uber executável por padrão. Se o arquivo de build do Maven ou do Gradle produzir um Uber JAR executável, o ambiente de execução iniciará seu aplicativo executando um aplicativo Uber JAR.

Como alternativa, o App Engine usará o conteúdo do campo entrypoint opcional no arquivo app.yaml. Por exemplo:

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

Em que o jar YOUR-ARTIFACT.jar do aplicativo precisa:

  • estar no diretório raiz com o arquivo app.yaml;
  • conter uma entrada Main-Class no arquivo de metadados META-INF/MANIFEST.MF;
  • (opcional) conter uma entrada Class-Path com uma lista de caminhos relativos a outros jars dependentes. Eles serão enviados automaticamente com o aplicativo.

Para que o app receba solicitações HTTP, seu ponto de entrada precisa iniciar um servidor da Web que atenda na porta especificada pela variável de ambiente PORT. O valor da variável de ambiente PORT é definido dinamicamente pelo ambiente de exibição do App Engine. Esse valor não pode ser definido na seção env_variables do arquivo app.yaml.

Com um ponto de entrada personalizado, é possível construir e empacotar seu aplicativo como um arquivo JAR thin, que contém apenas o código do aplicativo e as dependências diretas. Ao implantar o aplicativo, o plug-in do App Engine fará upload apenas dos arquivos que foram alterados, em vez de todo o pacote uber JAR.

Certifique-se de usar a variável de ambiente PORT

Se você vir os avisos sobre a porta 8080 e o NGINX nos arquivos de registro do seu app, isso significará que o servidor da Web do aplicativo está atendendo na porta 8080 padrão. Isso impede que o App Engine use a camada NGINX para compactar as respostas HTTP. Recomendamos que você configure seu servidor da Web para responder a solicitações HTTP na porta especificada pela variável de ambiente PORT, normalmente 8081. Exemplo:

/*
 * 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();
  }
}

Compatibilidade com as versões anteriores do Java

Para saber as diferenças entre o Java 8 e a versão compatível mais recente, consulte Migrar do Java 8 para o ambiente de execução do Java mais recente.

Variáveis de ambiente

As seguintes variáveis de ambiente são definidas pelo ambiente de execução:

Variável de ambiente Descrição
GAE_APPLICATION O ID do aplicativo do App Engine. Esse ID tem o prefixo "region code~", como "e~" para aplicativos implantados na Europa.
GAE_DEPLOYMENT_ID O ID da implantação atual.
GAE_ENV O ambiente do App Engine. Defina como standard.
GAE_INSTANCE O ID da instância em que o serviço é executado no momento.
GAE_MEMORY_MB A quantidade de memória disponível para o processo do aplicativo em MB.
GAE_RUNTIME O ambiente de execução especificado no seu arquivo app.yaml.
GAE_SERVICE O nome do serviço especificado no seu arquivo app.yaml. Se nenhum nome de serviço for especificado, ele será definido como default.
GAE_VERSION O rótulo da versão atual do serviço.
GOOGLE_CLOUD_PROJECT O ID do projeto do Google Cloud associado ao aplicativo.
PORT A porta que recebe solicitações HTTP.
NODE_ENV (disponível apenas no ambiente de execução do Node.js) Definido como production quando o serviço for implantado.

É possível definir outras variáveis de ambiente no arquivo app.yaml, mas os valores acima não podem ser modificados, exceto para NODE_ENV.

HTTPS e proxies de encaminhamento

O App Engine encerra as conexões HTTPS no balanceador de carga e encaminha as solicitações para o aplicativo. Em alguns aplicativos, é necessário determinar o protocolo e o IP de solicitação originais. O endereço IP do usuário está disponível no cabeçalho X-Forwarded-For padrão. Os aplicativos que precisam dessa informação devem configurar o framework da Web para confiar no proxy.

Acesso ao sistema de arquivos

O ambiente de execução inclui um diretório /tmp gravável, e todos os outros diretórios têm acesso somente de leitura. A gravação em /tmp ocupa a memória do sistema.

Servidor de metadados

Cada instância do aplicativo pode usar o servidor de metadados do App Engine para consultar informações sobre a instância e o projeto.

É possível acessar o servidor de metadados por meio dos endpoints a seguir:

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

As solicitações enviadas ao servidor de metadados precisam incluir o cabeçalho da solicitação Metadata-Flavor: Google. Esse cabeçalho indica que a solicitação foi enviada para recuperar valores de metadados.

A tabela a seguir lista os endpoints em que é possível fazer solicitações HTTP para metadados específicos.

Endpoint de metadados Descrição
/computeMetadata/v1/project/numeric-project-id Número do projeto atribuído ao seu projeto.
/computeMetadata/v1/project/project-id ID do projeto atribuído ao seu projeto.
/computeMetadata/v1/instance/region A região em que a instância está em execução.
/computeMetadata/v1/instance/service-accounts/default/aliases
/computeMetadata/v1/instance/service-accounts/default/email E-mail da conta de serviço padrão atribuído ao seu projeto.
/computeMetadata/v1/instance/service-accounts/default/ Lista todas as contas de serviço padrão do seu projeto.
/computeMetadata/v1/instance/service-accounts/default/scopes Lista todos os escopos compatíveis com as contas de serviço padrão.
/computeMetadata/v1/instance/service-accounts/default/token Retorna o token de autenticação que pode ser usado para autenticar o aplicativo em outras Google Cloud APIs.

Por exemplo, para recuperar o ID do projeto, envie uma solicitação para http://metadata.google.internal/computeMetadata/v1/project/project-id.