Java Runtime Environment

O tempo de execução Java é a pilha de software responsável por instalar o código do seu serviço Web e as respetivas dependências, bem como executar o seu serviço.

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

runtime: javaVERSION

Onde VERSION é o MAJORnúmero da versão do Java. Por exemplo, para usar a versão mais recente do Java, o Java 21, especifique 21.

Para outras versões do Java suportadas e a versão do Ubuntu correspondente à sua versão do Java, consulte a programação de suporte de tempo de execução.

Antes de começar

  1. Transfira a versão mais recente da CLI do Google Cloud ou atualize a CLI gcloud para a versão atual:

    gcloud components update
    
  2. Para implementar através do Maven, tem de adicionar o App Engine Maven Plugin ao ficheiro pom.xml:

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

    Outras opções de implementação incluem a utilização do comando gcloud app deploy ou o plugin do App Engine para o Gradle.

  3. Siga as instruções da sua framework de aplicações para configurar a compilação de um ficheiro executável JAR.

Compatibilidade com frameworks

Com o tempo de execução Java do App Engine, pode implementar ficheiros JAR executáveis. Os tempos de execução não incluem nenhuma framework de publicação na Web, o que significa que não está limitado a usar frameworks ou bibliotecas baseadas em servlets. Use as suas dependências nativas ou pilhas de rede, como a biblioteca Netty.

Não está limitado a estas frameworks e recomendamos que experimente a sua preferida, como Grails, Blade, Play!, Vaadin ou jHipster.

Implemente projetos de origem Maven no tempo de execução Java

Pode implementar o seu projeto Maven como código fonte e criá-lo e implementá-lo usando os buildpacks do Google Cloud.

Para implementar um projeto Maven como código fonte, aceda ao diretório de nível superior do projeto e escreva:

gcloud app deploy pom.xml

Os registos de compilação e implementação são transmitidos e pode ver os registos detalhados na secção Histórico do Cloud Build na Google Cloud consola.

Usar executáveis do GraalVM

O tempo de execução Java do ambiente padrão do App Engine suporta executáveis de imagens nativas do GraalVM. Depois de compilar a sua app Java numa imagem nativa do GraalVM, pode usar a definição entrypoint no ficheiro app.yaml para apontar para o ficheiro executável.

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

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

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

Versão do Java

A versão mais recente do Java suportada é a 21. O tempo de execução do Java usa a versão estável mais recente da versão especificada no ficheiro app.yaml. O App Engine é atualizado automaticamente para novas versões de lançamentos de patches, mas não atualiza automaticamente a versão secundária.

Por exemplo, a sua aplicação pode ser implementada no Java 21.0.4 e atualizada automaticamente para a versão Java 21.0.5 numa implementação posterior da plataforma gerida, mas não é atualizada automaticamente para o Java 22.

Para saber como atualizar a sua versão do Java, consulte o artigo Atualize uma aplicação existente.

O ambiente Open JDK do tempo de execução

O App Engine executa apps Java num contentor protegido pelo gVisor numa distribuição Ubuntu Linux atualizada e no openjdk-17-jdk suportado para o tempo de execução do Java 17 ou openjdk-21-jdk para o tempo de execução do Java 21.

Para ver as versões do Ubuntu suportadas para a sua versão do Java, consulte a Programação de suporte de tempo de execução.

O App Engine mantém a imagem base e atualiza o pacote OpenJDK 17 e OpenJDK 21, sem que tenha de reimplementar a sua app.

A sua app implementada está localizada no diretório /workspace do tempo de execução. Também está acessível através de um link simbólico em /srv.

Lançamentos do App Engine Java

Todos os artefactos 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 mais informações sobre como declarar e gerir dependências, consulte o artigo Especificar dependências.

Arranque da aplicação

As frameworks, como o Spring Boot, o Micronaut e o Ktor, criam um ficheiro JAR executável JAR por predefinição. Se o seu ficheiro de compilação do Maven ou Gradle produzir um Uber JAR executável, o tempo de execução inicia a sua aplicação executando uma aplicação Uber JAR.

Em alternativa, o App Engine usa o conteúdo do campo entrypoint opcional no seu ficheiro app.yaml. Por exemplo:

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

Onde o JAR da aplicação de exemplo YOUR-ARTIFACT.jar tem de:

  • Estar no diretório raiz com o ficheiro app.yaml.
  • Contenha uma entrada Main-Class no respetivo ficheiro de metadados META-INF/MANIFEST.MF.
  • Opcionalmente, pode conter uma entrada Class-Path com uma lista de caminhos relativos para outros ficheiros JAR dependentes. Estes são carregados automaticamente com a aplicação.

Para que a sua app receba pedidos HTTP, o ponto de entrada deve iniciar um servidor Web que escute na porta especificada pela variável de ambiente PORT. O valor da PORT variável de ambiente é definido dinamicamente pelo ambiente de publicação do App Engine. Este valor não pode ser definido na secção env_variables do ficheiro app.yaml.

Com um ponto de entrada personalizado, pode criar e embalar a sua aplicação como um ficheiro JAR simples que contém apenas o código da aplicação e as dependências diretas. Quando implementar a sua aplicação, o plug-in do App Engine só carrega os ficheiros que foram alterados, em vez do pacote JAR completo.

Certifique-se de que usa a variável de ambiente PORT

Se vir os avisos sobre a porta 8080 e o NGINX nos ficheiros de registo da app, o servidor Web da app está a escutar na porta predefinida 8080. Isto impede que o App Engine use a respetiva camada NGINX para comprimir as respostas HTTP. Recomendamos que configure o seu servidor Web para responder a pedidos HTTP na porta especificada pela variável de ambiente PORT, normalmente 8081. Por 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 versões anteriores do Java

Para ver as diferenças entre o Java 8 e a versão mais recente do Java suportada, consulte o artigo Migre do Java 8 para o tempo de execução do Java mais recente.

Variáveis de ambiente

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

Variável de ambiente Descrição
GAE_APPLICATION O ID da sua aplicação do App Engine. Este ID tem o prefixo "region code~", como "e~" para aplicações implementadas na Europa.
GAE_DEPLOYMENT_ID O ID da implementação atual.
GAE_ENV O ambiente do App Engine. Definido como standard.
GAE_INSTANCE O ID da instância na qual o seu serviço está atualmente em execução.
GAE_MEMORY_MB A quantidade de memória disponível para o processo da aplicação, em MB.
GAE_RUNTIME O tempo de execução especificado no ficheiro app.yaml.
GAE_SERVICE O nome do serviço especificado no ficheiro app.yaml. Se não for especificado nenhum nome de serviço, este é definido como default.
GAE_VERSION A etiqueta da versão atual do seu serviço.
GOOGLE_CLOUD_PROJECT O Google Cloud ID do projeto associado à sua aplicação.
PORT A porta que recebe pedidos HTTP.
NODE_ENV (disponível apenas no tempo de execução do Node.js) Definido como production quando o serviço é implementado.

Pode definir variáveis de ambiente adicionais no ficheiro app.yaml, mas os valores acima não podem ser substituídos, exceto o NODE_ENV.

HTTPS e proxies de encaminhamento

O App Engine termina as ligações HTTPS no equilibrador de carga e encaminha os pedidos para a sua aplicação. Algumas aplicações precisam de determinar o IP e o protocolo do pedido original. O endereço IP do utilizador está disponível no cabeçalho X-Forwarded-For padrão. As aplicações que requerem estas informações devem configurar a respetiva framework Web para confiar no proxy.

Acesso ao sistema de ficheiros

O tempo de execução inclui um diretório /tmp gravável, com todos os outros diretórios a terem acesso só de leitura. A escrita para /tmp ocupa memória do sistema.

Servidor de metadados

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

Pode aceder ao servidor de metadados através dos seguintes pontos finais:

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

Os pedidos enviados para o servidor de metadados têm de incluir o cabeçalho do pedido Metadata-Flavor: Google. Este cabeçalho indica que o pedido foi enviado com a intenção de obter valores de metadados.

A tabela seguinte lista os pontos finais onde pode fazer pedidos HTTP para metadados específicos:

Ponto final de metadados Descrição
/computeMetadata/v1/project/numeric-project-id O número do projeto atribuído ao seu projeto.
/computeMetadata/v1/project/project-id O ID do projeto atribuído ao seu projeto.
/computeMetadata/v1/instance/region A região em que a instância está a ser executada.
/computeMetadata/v1/instance/service-accounts/default/aliases
/computeMetadata/v1/instance/service-accounts/default/email O email da conta de serviço predefinido atribuído ao seu projeto.
/computeMetadata/v1/instance/service-accounts/default/ Apresenta todas as contas de serviço predefinidas do seu projeto.
/computeMetadata/v1/instance/service-accounts/default/scopes Lista todos os âmbitos suportados para as contas de serviço predefinidas.
/computeMetadata/v1/instance/service-accounts/default/token Devolve o token de autorização que pode ser usado para autenticar a sua aplicação noutras APIs Google Cloud.

Por exemplo, para obter o ID do projeto, envie um pedido para http://metadata.google.internal/computeMetadata/v1/project/project-id.