

# Construir funções do Lambda com Java
<a name="lambda-java"></a>

É possível executar o código Java no AWS Lambda. O Lambda fornece [runtimes](lambda-runtimes.md) para Java que executam seu código para processar eventos. O código é executado em um ambiente do Amazon Linux que inclui credenciais da AWS de uma função do AWS Identity and Access Management (IAM) que você gerencia.

O Lambda oferece suporte aos seguintes runtimes Java.<a name="java-runtimes"></a>


| Nome | Identificador | Sistema operacional | Data da substituição | Bloquear a criação de funções | Bloquear a atualização de funções | 
| --- | --- | --- | --- | --- | --- | 
|  Java 25  |  `java25`  |  Amazon Linux 2023  |   30 de junho de 2029   |   31 de julho de 2029   |   31 de agosto de 2029   | 
|  Java 21  |  `java21`  |  Amazon Linux 2023  |   30 de junho de 2029   |   31 de julho de 2029   |   31 de agosto de 2029   | 
|  Java 17  |  `java17`  |  Amazon Linux 2  |   30º de junho de 2027   |   31º de julho de 2027   |   31 de agosto de 2027   | 
|  Java 11  |  `java11`  |  Amazon Linux 2  |   30º de junho de 2027   |   31º de julho de 2027   |   31 de agosto de 2027   | 
|  Java 8  |  `java8.al2`  |  Amazon Linux 2  |   30º de junho de 2027   |   31º de julho de 2027   |   31 de agosto de 2027   | 

A AWS fornece as bibliotecas para funções em Java a seguir. Essas bibliotecas estão disponíveis no [repositório central do Maven](https://search.maven.org/search?q=g:com.amazonaws).
+ [com.amazonaws:aws-lambda-java-core](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-core) (obrigatória): define as interfaces do método do manipulador e o objeto de contexto que o runtime transmite ao manipulador. Se você definir seus próprios tipos de entrada, esta será a única biblioteca necessária.
+ [com.amazonaws:aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-events): tipos de entrada para eventos de serviços que invocam funções do Lambda.
+ [com.amazonaws:aws-lambda-java-log4j2](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-log4j2): uma biblioteca appender do Apache Log4j 2 que você pode usar para adicionar o ID de solicitação da invocação atual aos [logs de função](java-logging.md).
+ [AWS SDK for Java 2.0](https://github.com/aws/aws-sdk-java-v2): o AWS SDK oficial para a linguagem de programação Java.

Adicione-as à sua definição de compilação da seguinte forma:

------
#### [ Gradle ]

```
dependencies {
    implementation 'com.amazonaws:aws-lambda-java-core:1.2.2'
    implementation 'com.amazonaws:aws-lambda-java-events:3.11.1'
    runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.1'
}
```

------
#### [ Maven ]

```
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-core</artifactId>
      <version>1.2.2</version>
    </dependency>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-events</artifactId>
      <version>3.11.1</version>
    </dependency>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-log4j2</artifactId>
      <version>1.5.1</version>
    </dependency>
  </dependencies>
```

------

**Importante**  
Não use componentes privados da API JDK, como campos, métodos ou classes privadas. Componentes de API não públicos podem ser alterados ou removidos em qualquer atualização, causando falha na aplicação.

**Para criar uma função em Java**

1. Abra o [console do lambda](https://console.aws.amazon.com/lambda).

1. Escolha a opção **Criar função**.

1. Configure as seguintes opções:
   + **Nome da função**: digite um nome para a função.
   + **Runtime**: escolha **Java 25**.

1. Escolha a opção **Criar função**.

O console cria uma função do Lambda com uma classe de manipulador chamada `Hello`. Como Java é uma linguagem compilada, não é possível visualizar nem editar o código-fonte no console do Lambda, mas você pode modificar a configuração dele, invocá-lo e configurar acionadores.

**nota**  
Para começar com o desenvolvimento de aplicativos no ambiente local, implante um dos [aplicativos de exemplo](java-samples.md) disponíveis no repositório do GitHub deste guia.

A classe `Hello` tem uma função chamada `handleRequest` que utiliza um objeto de evento e um objeto de contexto. Esta é a [função de manipulador](java-handler.md) que o Lambda chama quando a função é invocada. O runtime da função do Java recebe eventos de invocação do Lambda e os transmite ao handler. Na configuração da função, o valor do manipulador é `example.Hello::handleRequest`.

Para atualizar o código da função, crie um pacote de implantação, que é um arquivo .zip que contém o código da função. À medida que o desenvolvimento da função progredir, você desejará armazenar o código da função no controle de origem, adicionar bibliotecas e automatizar implantações. Comece [criando um pacote de implantação](java-package.md) e atualizando o seu código na linha de comando.

O runtime transmite um objeto de contexto para o handler, além do evento de invocação. O [objeto de contexto](java-context.md) contém informações adicionais sobre a invocação, a função e o ambiente de execução. Outras informações estão disponíveis de variáveis de ambiente.

Sua função do Lambda é fornecida com um grupo de logs do CloudWatch Logs. O runtime envia detalhes sobre cada invocação para o CloudWatch Logs. Ele retransmite quaisquer [logs que sua função produz](java-logging.md) durante a invocação. Se a função retornar um erro, o Lambda formatará o erro e o retornará para o chamador.

**Topics**
+ [Definir o manipulador da função do Lambda em Java](java-handler.md)
+ [Implantar funções do Lambda em Java com arquivos .zip ou JAR](java-package.md)
+ [Implantar funções do Lambda em Java com imagens de contêiner](java-image.md)
+ [Como trabalhar com camadas para funções do Lambda em Java](java-layers.md)
+ [Personalização da serialização para funções do Lambda em Java](java-custom-serialization.md)
+ [Personalizar o comportamento de startup de runtime para as funções do Lambda](java-customization.md)
+ [Usar o objeto de contexto do Lambda para recuperar informações das funções em Java](java-context.md)
+ [Registrar em log e monitorar funções do Lambda em Java](java-logging.md)
+ [Instrumentação do código Java no AWS Lambda](java-tracing.md)
+ [Aplicativos de exemplo Java para o AWS Lambda](java-samples.md)

# Definir o manipulador da função do Lambda em Java
<a name="java-handler"></a>

O *manipulador* da função do Lambda é o método no código da função que processa eventos. Quando sua função é invocada, o Lambda executa o método do manipulador. A função é executada até que o manipulador retorne uma resposta, seja encerrado ou atinja o tempo limite.

Esta página descreve como trabalhar com manipuladores de função do Lambda em Java, incluindo opções para a configuração de projeto, as convenções de nomenclatura e as práticas recomendadas. Além disso, esta página apresenta um exemplo de uma função do Lambda em Java que aceita informações sobre um pedido, produz um recibo em formato de texto e armazena esse arquivo em um bucket do Amazon Simple Storage Service (Amazon S3). Para obter mais informações sobre como implantar a função após gravá-la, consulte [Implantar funções do Lambda em Java com arquivos .zip ou JAR](java-package.md) ou [Implantar funções do Lambda em Java com imagens de contêiner](java-image.md).

**Topics**
+ [Configuração do projeto de manipulador em Java](#java-handler-setup)
+ [Exemplo de código da função do Lambda em Java](#java-example-code)
+ [Definições de classe válidas para manipuladores Java](#java-handler-signatures)
+ [Convenções de nomenclatura para manipuladores](#java-example-naming)
+ [Definição e acesso ao objeto do evento de entrada](#java-handler-input)
+ [Acesso e uso do objeto de contexto do Lambda](#java-example-context)
+ [Uso do SDK da AWS para Java v2 em seu manipulador](#java-example-sdk-usage)
+ [Acesso a variáveis de ambiente](#java-example-envvars)
+ [Usar o estado global](#java-handler-state)
+ [Práticas recomendadas de código para as funções do Lambda em Java](#java-best-practices)

## Configuração do projeto de manipulador em Java
<a name="java-handler-setup"></a>

Ao trabalhar com funções do Lambda em Java, o processo envolve escrever seu código, compilá-lo e implantar os artefatos compilados no Lambda. Você pode inicializar um projeto Java Lambda de várias maneiras. Por exemplo, você pode usar ferramentas como o [Maven Archetype para funções Lambda](https://github.com/aws/aws-sdk-java-v2/tree/master/archetypes/archetype-lambda), a CLI do AWS SAM [ comando sam init](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-init.html), ou até mesmo uma configuração de projeto Java padrão em seu IDE preferido, como IntelliJ IDEA ou Visual Studio Code. Você também pode criar a estrutura de arquivos necessária manualmente.

Um projeto típico de função do Lambda em Java segue esta estrutura geral:

```
/project-root
    └ src
        └ main
            └ java
                └ example
                    └ OrderHandler.java (contains main handler)
                    └ <other_supporting_classes>
     └ build.gradle OR pom.xml
```

Você pode usar o Maven ou o Gradle para criar seu projeto e gerenciar dependências.

A lógica principal do manipulador da sua função reside em um arquivo Java no diretório `src/main/java/example`. No exemplo desta página, chamamos esse arquivo de `OrderHandler.java`. Além desse arquivo, você pode incluir mais classes Java conforme necessário. Ao implantar sua função no Lambda, certifique-se de especificar a classe Java que contém o método manipulador principal que o Lambda deve invocar durante uma invocação.

## Exemplo de código da função do Lambda em Java
<a name="java-example-code"></a>

O exemplo de código apresentado a seguir para uma função do Lambda em Java 21 aceita informações sobre um pedido, produz um recibo em formato de texto e armazena esse arquivo em um bucket do Amazon S3.

**Example `OrderHandler.java`Função do Lambda em**  

```
package example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;

import java.nio.charset.StandardCharsets;

/**
 * Lambda handler for processing orders and storing receipts in S3.
 */
public class OrderHandler implements RequestHandler<OrderHandler.Order, String> {

    private static final S3Client S3_CLIENT = S3Client.builder().build();

    /**
     * Record to model the input event.
     */
    public record Order(String orderId, double amount, String item) {}

    @Override
    public String handleRequest(Order event, Context context) {
        try {
            // Access environment variables
            String bucketName = System.getenv("RECEIPT_BUCKET");
            if (bucketName == null || bucketName.isEmpty()) {
                throw new IllegalArgumentException("RECEIPT_BUCKET environment variable is not set");
            }

            // Create the receipt content and key destination
            String receiptContent = String.format("OrderID: %s\nAmount: $%.2f\nItem: %s",
                    event.orderId(), event.amount(), event.item());
            String key = "receipts/" + event.orderId() + ".txt";

            // Upload the receipt to S3
            uploadReceiptToS3(bucketName, key, receiptContent);

            context.getLogger().log("Successfully processed order " + event.orderId() +
                    " and stored receipt in S3 bucket " + bucketName);
            return "Success";

        } catch (Exception e) {
            context.getLogger().log("Failed to process order: " + e.getMessage());
            throw new RuntimeException(e);
        }
    }

    private void uploadReceiptToS3(String bucketName, String key, String receiptContent) {
        try {
            PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                    .bucket(bucketName)
                    .key(key)
                    .build();

            // Convert the receipt content to bytes and upload to S3
            S3_CLIENT.putObject(putObjectRequest, RequestBody.fromBytes(receiptContent.getBytes(StandardCharsets.UTF_8)));
        } catch (S3Exception e) {
            throw new RuntimeException("Failed to upload receipt to S3: " + e.awsErrorDetails().errorMessage(), e);
        }
    }
}
```

Este arquivo `OrderHandler.java` contém as seguintes seções de código:
+ `package example`: em Java, isso pode ser qualquer coisa, mas deve corresponder à estrutura de diretórios do seu projeto. Aqui, usamos `package example` porque a estrutura de diretórios é `src/main/java/example`.
+ Declarações de `import`: use-as para importar as classes Java que sua função do Lambda requer.
+ `public class OrderHandler ...`: isso define sua classe Java e deve ser uma [definição de classe válida](#java-handler-signatures).
+ `private static final S3Client S3_CLIENT ...`: isso inicializa um cliente do S3 fora de qualquer um dos métodos da classe. Isso faz com que o Lambda execute esse código durante a fase de [inicialização](lambda-runtime-environment.md#runtimes-lifecycle-ib).
+ `public record Order ...`: define o formato do evento de entrada esperado neste [registro](https://openjdk.org/jeps/395) Java personalizado.
+ `public String handleRequest(Order event, Context context)`: este é o **método principal do manipulador**, que contém a lógica principal da sua aplicação.
+ `private void uploadReceiptToS3(...) {}`: este é um método auxiliar que é referenciado pelo método principal do manipulador `handleRequest`.

### Exemplo de arquivo build.gradle e pom.xml
<a name="java-gradle-maven-example"></a>

O arquivo `build.gradle` ou `pom.xml` a seguir acompanha essa função.

------
#### [ build.gradle ]

```
plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.amazonaws:aws-lambda-java-core:1.2.3'
    implementation 'software.amazon.awssdk:s3:2.28.29'
    implementation 'org.slf4j:slf4j-nop:2.0.16'
}

task buildZip(type: Zip) {
    from compileJava
    from processResources
    into('lib') {
        from configurations.runtimeClasspath
    }
}

java {
    sourceCompatibility = JavaVersion.VERSION_21
    targetCompatibility = JavaVersion.VERSION_21
}

build.dependsOn buildZip
```

------
#### [ pom.xml ]

```
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>example-java</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>example-java-function</name>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
            <version>2.28.29</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>2.0.16</version>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.2</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.4.1</version>
                <configuration>
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*</exclude>
                                <exclude>META-INF/versions/**</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.13.0</version>
                <configuration>
                    <release>21</release>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

------

Para que esta função funcione corretamente, seu [ perfil de execução](lambda-intro-execution-role.md) deve permitir a ação `s3:PutObject`. Além disso, certifique-se de definir a variável de ambiente `RECEIPT_BUCKET`. Após uma invocação com êxito, o bucket do Amazon S3 deve conter um arquivo de recibo.

**nota**  
Essa função pode exigir configurações adicionais para ser executada com sucesso sem atingir o tempo limite. Recomendamos configurar 256 MB de memória e um tempo limite de 10 segundos. A primeira invocação pode levar mais tempo devido a uma [inicialização a frio](lambda-runtime-environment.md#cold-start-latency). As invocações subsequentes devem ser executadas muito mais rapidamente devido à reutilização do ambiente de execução.

## Definições de classe válidas para manipuladores Java
<a name="java-handler-signatures"></a>

Para definir sua classe, a biblioteca [ aws-lambda-java-core](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-core) define duas interfaces para métodos do manipulador. Use as interfaces fornecidas para simplificar a configuração do manipulador e validar a assinatura do método no momento da compilação.
+ [ com.amazonaws.services.lambda.runtime.RequestHandler](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/RequestHandler.java)
+ [ com.amazonaws.services.lambda.runtime.RequestStreamHandler](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/RequestStreamHandler.java)

A interface `RequestHandler` é um tipo genérico que usa dois parâmetros: o tipo de entrada e o tipo de saída. Ambos os tipos devem ser objetos. Neste exemplo, nossa classe `OrderHandler` implementa `RequestHandler<OrderHandler.Order, String>`. O tipo de entrada é o registro `Order` que definimos dentro da classe, e o tipo de saída é `String`.

```
public class OrderHandler implements RequestHandler<OrderHandler.Order, String> {
    ...
}
```

Quando você usa essa interface, o runtime do Java desserializa o evento no objeto com o tipo de entrada e serializa a saída em texto. Use essa interface quando a serialização interna funcionar com seus tipos de entrada e saída.

Para usar sua própria serialização, você pode implemente a interface `RequestStreamHandler`. Com essa interface, o Lambda transmite ao seu manipulador uma transmissão de entrada e uma de saída. O manipulador lê bytes do fluxo de entrada, grava no fluxo de saída e retorna um void. Para ver um exemplo disso usando o runtime do Java 21, consulte [ HandlerStream.java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic/src/main/java/example/HandlerStream.java).

Se você estiver trabalhando somente com tipos básicos e genéricos (ou seja, `String`, `Integer`, `List` ou `Map`) em sua função Java, não precisará implementar uma interface. Por exemplo, se sua função recebe uma entrada `Map<String, String>` e retorna um `String`, sua definição de classe e assinatura do manipulador podem ter a seguinte aparência:

```
public class ExampleHandler {
    public String handleRequest(Map<String, String> input, Context context) {
        ...
    }
}
```

Além disso, quando você não implementa uma interface, o objeto de [contexto](java-context.md) é opcional. Por exemplo, sua definição de classe e assinatura de manipulador podem ter a seguinte aparência:

```
public class NoContextHandler {
   public String handleRequest(Map<String, String> input) {
        ...
   }
}
```

## Convenções de nomenclatura para manipuladores
<a name="java-example-naming"></a>

Para funções do Lambda em Java, se você estiver implementando a interface `RequestHandler` ou `RequestStreamHandler`, seu método de manipulador principal deverá ser nomeado `handleRequest`. Além disso, inclua a tag `@Override` acima do seu método `handleRequest`. Ao implantar sua função no Lambda, especifique o manipulador principal na configuração da sua função no seguinte formato:
+ *<package>*.*<Class>*: por exemplo, `example.OrderHandler`.

Para funções do Lambda em Java que não implementam a interface `RequestHandler` ou `RequestStreamHandler`, você pode usar qualquer nome para o manipulador. Ao implantar sua função no Lambda, especifique o manipulador principal na configuração da sua função no seguinte formato:
+ *<package>*.*<Class>*::*<handler\$1method\$1name>*: por exemplo, `example.Handler::mainHandler`.

## Definição e acesso ao objeto do evento de entrada
<a name="java-handler-input"></a>

O formato de entrada JSON é o mais comum e padrão para funções do Lambda. Neste exemplo, a função espera uma entrada semelhante à seguinte:

```
{
    "orderId": "12345",
    "amount": 199.99,
    "item": "Wireless Headphones"
}
```

Ao trabalhar com funções do Lambda em Java 17, é possível definir o formato do evento de entrada esperado como um registro em Java. Neste exemplo, definimos um registro dentro da classe `OrderHandler` para representar um objeto `Order`:

```
public record Order(String orderId, double amount, String item) {}
```

Esse registro corresponde ao formato de entrada esperado. Após definir o registro, você pode escrever uma assinatura de manipulador que aceita uma entrada JSON que está em conformidade com a definição do registro. O runtime do Java automaticamente desserializa esse JSON em um objeto Java. Em seguida, você pode acessar os campos do objeto. Por exemplo, `event.orderId` recupera o valor de `orderId` da entrada original.

**nota**  
Os registros Java são um atributo somente dos runtimes do Java 17 e versões mais recentes. Em todos os runtimes do Java, é possível usar uma classe para representar os dados do evento. Nesses casos, você pode usar uma biblioteca como [jackson](https://github.com/FasterXML/jackson) para desserializar as entradas JSON.

### Outros tipos de eventos de entrada
<a name="java-input-event-types"></a>

Há muitos eventos de entrada possíveis para funções do Lambda em Java:
+ `Integer`, `Long`, `Double`, etc. – o evento é um número sem formatação adicional, por exemplo, `3.5`. O runtime do Java converte o valor em um objeto do tipo especificado.
+ `String` – o evento é uma string JSON, incluindo aspas, por exemplo, `“My string”`. O runtime converte o valor em um objeto `String` sem aspas.
+ `List<Integer>`, `List<String>`, `List<Object>`, etc. – o evento é uma matriz JSON. O runtime o desserializa em um objeto da interface ou tipo especificado.
+ `InputStream`: o evento é qualquer tipo JSON. O runtime transmite um fluxo de bytes do documento ao manipulador sem modificação. Desserialize a entrada e grave a saída em um fluxo de saída.
+ Tipo de biblioteca: para eventos enviados por outros serviços da AWS, use os tipos na biblioteca [aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-events). Por exemplo, se sua função do Lambda for invocada pelo Amazon Simple Queue Service (SQS), use o objeto `SQSEvent` como entrada.

## Acesso e uso do objeto de contexto do Lambda
<a name="java-example-context"></a>

O [objeto de contexto](java-context.md) do Lambda contém informações sobre a invocação, a função e o ambiente de execução. Neste exemplo, o objeto de contexto é do tipo `com.amazonaws.services.lambda.runtime.Context` e é o segundo argumento da função principal do manipulador.

```
public String handleRequest(Order event, Context context) {
    ...
}
```

Se sua classe implementa a interface [ RequestHandler](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/RequestHandler.java) ou [ RequestStreamHandler](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/RequestStreamHandler.java), o objeto de contexto é um argumento obrigatório. Caso contrário, o objeto de contexto é opcional. Para obter mais informações sobre as assinaturas de manipulador válidas e aceitas, consulte [Definições de classe válidas para manipuladores Java](#java-handler-signatures).

Se você realizar chamadas a outros serviços usando o AWS SDK, o objeto de contexto será necessário em algumas áreas importantes. Por exemplo, para produzir logs de funções para o Amazon CloudWatch, você pode usar o método `context.getLogger()` para obter um objeto `LambdaLogger` para registro em log. Neste exemplo, podemos usar o logger para registrar uma mensagem de erro se o processamento falhar por qualquer motivo:

```
context.getLogger().log("Failed to process order: " + e.getMessage());
```

Fora do registro em log, é possível usar o objeto de contexto para realizar o monitoramento da função. Para obter mais informações sobre o objeto de contexto, consulte [Usar o objeto de contexto do Lambda para recuperar informações das funções em Java](java-context.md).

## Uso do SDK da AWS para Java v2 em seu manipulador
<a name="java-example-sdk-usage"></a>

Frequentemente, você usará as funções do Lambda para interagir com ou fazer atualizações em outros recursos da AWS. A maneira mais simples de interagir com esses recursos é usar o SDK da AWS para Java v2.

**nota**  
O SDK da AWS para Java (v1) está em modo de manutenção e terá o suporte encerrado em 31 de dezembro de 2025. Recomendamos que você use somente o SDK da AWS para Java v2 daqui em diante.

Para adicionar dependências do SDK à sua função, adicione-as em seu arquivo `build.gradle` para Gradle ou `pom.xml` para Maven. Recomendamos adicionar somente as bibliotecas necessárias para sua função. No código de exemplo anterior, usamos a biblioteca `software.amazon.awssdk.services.s3`. No Gradle, você pode adicionar essa dependência adicionando a seguinte linha na seção de dependências do seu `build.gradle`:

```
implementation 'software.amazon.awssdk:s3:2.28.29'
```

No Maven, adicione as seguintes linhas na seção `<dependencies>` do seu `pom.xml`:

```
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>s3</artifactId>
        <version>2.28.29</version>
    </dependency>
```

**nota**  
Esta pode não ser a versão mais recente do SDK. Escolha a versão apropriada do SDK para a sua aplicação.

Em seguida, importe as dependências diretamente na sua classe Java:

```
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
```

O código de exemplo então inicializa um cliente do Amazon S3 da seguinte maneira:

```
private static final S3Client S3_CLIENT = S3Client.builder().build();
```

Neste exemplo, inicializamos nosso cliente do Amazon S3 fora da função do manipulador principal para evitar a necessidade que inicializá-lo a cada vez que nossa função é invocada. Após inicializar o cliente do SDK, você pode usá-lo para interagir com outros serviços da AWS. O código de exemplo chama a API `PutObject` do Amazon S3 da seguinte forma:

```
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
    .bucket(bucketName)
    .key(key)
    .build();

// Convert the receipt content to bytes and upload to S3
S3_CLIENT.putObject(putObjectRequest, RequestBody.fromBytes(receiptContent.getBytes(StandardCharsets.UTF_8)));
```

## Acesso a variáveis de ambiente
<a name="java-example-envvars"></a>

No código do manipulador, você pode fazer referência a qualquer [variável de ambiente](configuration-envvars.md) ao usar o método `System.getenv()`. Neste exemplo, referenciamos a variável de ambiente `RECEIPT_BUCKET` definida usando a seguinte linha de código:

```
String bucketName = System.getenv("RECEIPT_BUCKET");
if (bucketName == null || bucketName.isEmpty()) {
    throw new IllegalArgumentException("RECEIPT_BUCKET environment variable is not set");
}
```

## Usar o estado global
<a name="java-handler-state"></a>

O Lambda executa seu código estático e o construtor de classe durante a [fase de inicialização](lambda-runtime-environment.md#runtimes-lifecycle-ib) antes de invocar a função pela primeira vez. Os recursos criados durante a inicialização permanecem na memória entre as invocações, para que você possa evitar ter que criá-los toda vez que invocar sua função.

No código de exemplo, o código de inicialização do cliente do S3 está fora do método do manipulador principal. O runtime inicializa o cliente antes que a função manipule seu primeiro evento e o cliente permanece disponível para reutilização em todas as invocações.

## Práticas recomendadas de código para as funções do Lambda em Java
<a name="java-best-practices"></a>

Adote as diretrizes da lista a seguir para usar as práticas recomendadas de codificação ao compilar suas funções do Lambda:
+ **Separe o manipulador do Lambda da lógica central.** Isso permite que você crie uma função mais fácil para teste de unidade.
+ **Controle as dependências no pacote de implantação da função. ** O ambiente de execução do AWS Lambda contém várias bibliotecas. Para habilitar o conjunto de recursos e atualizações de segurança mais recente, o Lambda atualizará periodicamente essas bibliotecas. Essas atualizações podem introduzir alterações sutis ao comportamento de sua função do Lambda. Para ter controle total das dependências usadas por sua função, empacote todas as dependências em seu pacote de implantação. 
+ **Minimize a complexidade de suas dependências.** Prefira frameworks mais simples que sejam carregados rapidamente no startup do [ambiente de execução](lambda-runtime-environment.md). Por exemplo, prefira frameworks de injeção de dependência Java (IoC) mais simples, como [Dagger](https://google.github.io/dagger/) ou [Guice](https://github.com/google/guice), em vez de frameworks mais complexos, como o [Spring Framework](https://github.com/spring-projects/spring-framework).
+ **Minimize o tamanho do pacote de implantação para conter somente o necessário para o runtime. ** Isso reduzirá a quantidade de tempo necessária para que seu pacote de implantação seja obtido por download e desempacotado antes da invocação. Para funções criadas em .Java, evite carregar a biblioteca do AWS SDK inteira como parte do pacote de implantação. Em vez disso, dependa seletivamente dos módulos que coletam os componentes do SDK necessários (por exemplo, DynamoDB, módulos do SDK do Amazon S3 e [bibliotecas principais do Lambda](https://github.com/aws/aws-lambda-java-libs)).

**Aproveite a reutilização do ambiente de execução para melhorar a performance da função.** Inicialize clientes SDK e conexões de banco de dados fora do manipulador de funções e armazene em cache os ativos estáticos localmente no diretório `/tmp`. As invocações subsequentes processadas pela mesma instância da função podem reutilizar esses recursos. Isso economiza custos reduzindo o runtime da função.

Para evitar possíveis vazamentos de dados entre invocações, não use o ambiente de execução para armazenar dados do usuário, eventos ou outras informações com implicações de segurança. Se sua função depende de um estado mutável que não pode ser armazenado na memória dentro do manipulador, considere criar uma função separada ou versões separadas de uma função para cada usuário.

**Use uma diretiva de keep-alive para manter conexões persistentes.** O Lambda limpa conexões ociosas ao longo do tempo. A tentativa de reutilizar uma conexão ociosa ao invocar uma função resultará em um erro de conexão. Para manter sua conexão persistente, use a diretiva keep-alive associada ao runtime. Para obter um exemplo, consulte [Reutilizar conexões com keep-alive em Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html).

**Use [variáveis de ambiente](configuration-envvars.md) para passar parâmetros operacionais para sua função.** Por exemplo, se estiver gravando em um bucket do Amazon S3, em vez fixar no código o nome do bucket em que você está gravando, configure o nome do bucket como uma variável de ambiente.

**Evite usar invocações recursivas** em sua função do Lambda, em que a função invoca a si mesma ou inicia um processo que pode invocar a função novamente. Isso pode levar a um volume não intencional de invocações da função e a custos elevados. Se você observar um volume não intencional de invocações, defina a simultaneidade reservada da função como `0` imediatamente para limitar todas as invocações da função enquanto atualiza o código.

**Não use APIs não documentadas e não públicas** no código da função Lambda. Para os tempos de execução gerenciados pelo AWS Lambda, o Lambda aplica periodicamente atualizações funcionais e de segurança às APIs internas do Lambda. Essas atualizações internas da API podem ser incompatíveis com versões anteriores, gerando consequências não intencionais, como falhas de invocação, caso sua função tenha dependência nessas APIs não públicas. Consulte [a referência da API](https://docs.aws.amazon.com/lambda/latest/api/welcome.html) para obter uma lista de APIs disponíveis publicamente.

**Escreva um código idempotente.** Escrever um código idempotente para suas funções garante que eventos duplicados sejam tratados da mesma maneira. Seu código deve validar eventos adequadamente e lidar corretamente com eventos duplicados. Para obter mais informações, consulte [Como torno minha função do Lambda idempotente?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/).
+ **Evite usar o cache do DNS Java.** As funções do Lambda já armazenam as respostas de DNS em cache. Se usar outro cache do DNS, você poderá experimentar tempos limite de conexão.

  A classe `java.util.logging.Logger` pode habilitar indiretamente o cache do DNS da JVM. Para substituir as configurações padrão, defina [networkaddress.cache.ttl](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/InetAddress.html#inetaddress-caching-heading) como 0 antes de inicializar o `logger`. Exemplo:

  ```
  public class MyHandler {
    // first set TTL property
    static{
     java.security.Security.setProperty("networkaddress.cache.ttl" , "0");
    }
   // then instantiate logger
    var logger = org.apache.logging.log4j.LogManager.getLogger(MyHandler.class);
  }
  ```
+ **Reduza o tempo necessário para o Lambda desempacotar pacotes de implantação** criados em Java colocando seus arquivos `.jar` de dependências em um diretório lib/separado. Isso é mais rápido do que colocar todo o código de sua função em um único jar com um grande número de arquivos `.class`. Para obter instruções, consulte [Implantar funções do Lambda em Java com arquivos .zip ou JAR](java-package.md).

# Implantar funções do Lambda em Java com arquivos .zip ou JAR
<a name="java-package"></a>

O código da função do AWS Lambda consiste em scripts ou programas compilados e as dependências deles. Você usa um*pacote de implantação*para implantar seu código de função no Lambda. O Lambda é compatível com dois tipos de pacotes de implantação: imagens de contêiner e arquivos .zip. 

Esta página descreve como criar o seu pacote de implantação como um arquivo .zip ou Jar e, em seguida, usar o pacote para implantar o seu código de função para o AWS Lambda usando a AWS Command Line Interface (AWS CLI).

**Importante**  
O Java 25 introduziu suporte para caches antecipados (AOT). É altamente recomendável não usar caches AOT ao implantar suas funções como arquivamentos de arquivos.zip ou JAR, pois os caches podem causar um comportamento inesperado quando o Lambda atualiza o runtime gerenciado. Consulte [Caches antecipados (AOT) e CDS](java-customization.md#aot-cds-caches) para obter mais informações.

**Topics**
+ [Pré-requisitos](#java-package-prereqs)
+ [Ferramentas e bibliotecas](#java-package-libraries)
+ [Compilar um pacote de implantação com o Gradle](#java-package-gradle)
+ [Usar camadas para dependências](#java-package-layers)
+ [Compilar um pacote de implantação com o Maven](#java-package-maven)
+ [Upload de um pacote de implantação com o console do Lambda](#java-package-console)
+ [Carregar um pacote de implantação com a AWS CLI](#java-package-cli)
+ [Fazer upload de um pacote de implantação com o AWS SAM](#java-package-cloudformation)

## Pré-requisitos
<a name="java-package-prereqs"></a>

O AWS CLI é uma ferramenta de código aberto que permite interagir com os serviços do AWS usando comandos no shell da linha de comando. Para concluir as etapas desta seção, você deve ter a [versão 2 da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

## Ferramentas e bibliotecas
<a name="java-package-libraries"></a>

A AWS fornece as bibliotecas para funções em Java a seguir. Essas bibliotecas estão disponíveis no [repositório central do Maven](https://search.maven.org/search?q=g:com.amazonaws).
+ [com.amazonaws:aws-lambda-java-core](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-core) (obrigatória): define as interfaces do método do manipulador e o objeto de contexto que o runtime transmite ao manipulador. Se você definir seus próprios tipos de entrada, esta será a única biblioteca necessária.
+ [com.amazonaws:aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-events): tipos de entrada para eventos de serviços que invocam funções do Lambda.
+ [com.amazonaws:aws-lambda-java-log4j2](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-log4j2): uma biblioteca appender do Apache Log4j 2 que você pode usar para adicionar o ID de solicitação da invocação atual aos [logs de função](java-logging.md).
+ [AWS SDK for Java 2.0](https://github.com/aws/aws-sdk-java-v2): o AWS SDK oficial para a linguagem de programação Java.

Adicione-as à sua definição de compilação da seguinte forma:

------
#### [ Gradle ]

```
dependencies {
    implementation 'com.amazonaws:aws-lambda-java-core:1.2.2'
    implementation 'com.amazonaws:aws-lambda-java-events:3.11.1'
    runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.1'
}
```

------
#### [ Maven ]

```
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-core</artifactId>
      <version>1.2.2</version>
    </dependency>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-events</artifactId>
      <version>3.11.1</version>
    </dependency>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-log4j2</artifactId>
      <version>1.5.1</version>
    </dependency>
  </dependencies>
```

------

Para criar um pacote de implantação, compile o código e as dependências da sua função em um único arquivo .zip ou Java Archive (JAR). Para o Gradle, [use o tipo de compilação `Zip`](#java-package-gradle). Para o Apache Maven, [use o plugin Maven Shade](#java-package-maven). Para fazer o upload do seu pacote de implantação, use o console do Lambda, a API do Lambda ou o AWS Serverless Application Model (AWS SAM).

**nota**  
Para manter o pacote de implantação pequeno, empacote as dependências da função em camadas. As camadas permitem gerenciar as suas dependências de forma independente, podem ser usadas por várias funções e podem ser compartilhadas com outras contas. Para obter mais informações, consulte [Gerenciar dependências do Lambda com camadas](chapter-layers.md).

## Compilar um pacote de implantação com o Gradle
<a name="java-package-gradle"></a>

Para criar um pacote de implantação com o código e as dependências da sua função no Gradle, use o tipo de compilação `Zip`. Aqui está um exemplo de um [arquivo build.gradle completo de amostra](https://github.com/awsdocs/aws-lambda-developer-guide/blob/main/sample-apps/s3-java/build.gradle):

**Example build.gradle: tarefa de compilação**  

```
task buildZip(type: Zip) {
    into('lib') {
        from(jar)
        from(configurations.runtimeClasspath)
    }
}
```

Essa configuração de compilação produz um pacote de implantação no diretório `build/distributions`. Na instrução `into('lib')`, a tarefa `jar` monta um arquivo jar contendo suas classes principais em uma pasta denominada `lib`. Além disso, a tarefa `configurations.runtimeClassPath` copia bibliotecas de dependência do caminho de classe da compilação para a mesma pasta `lib`.

**Example build.gradle: dependências**  

```
dependencies {
    ...
    implementation 'com.amazonaws:aws-lambda-java-core:1.2.2'
    implementation 'com.amazonaws:aws-lambda-java-events:3.11.1'
    implementation 'org.apache.logging.log4j:log4j-api:2.17.1'
    implementation 'org.apache.logging.log4j:log4j-core:2.17.1'
    runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.17.1'
    runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.1'
    ...
}
```

O Lambda carrega arquivos JAR em Unicode em ordem alfabética. Se vários arquivos JAR no diretório `lib` contiverem a mesma classe, a primeira será usada. Use o script de shell a seguir para identificar classes duplicadas.

**Example test-zip.sh**  

```
mkdir -p expanded
unzip path/to/my/function.zip -d expanded
find ./expanded/lib -name '*.jar' | xargs -n1 zipinfo -1 | grep '.*.class' | sort | uniq -c | sort
```

## Usar camadas para dependências
<a name="java-package-layers"></a>

É possível empacotar as dependências da sua função em camadas para manter seu pacote de implantação pequeno e gerenciar dependências de forma independente. Para obter mais informações, consulte [Como trabalhar com camadas para funções do Lambda em Java](java-layers.md).

## Compilar um pacote de implantação com o Maven
<a name="java-package-maven"></a>

Para compilar um pacote de implantação com o Maven, use o [plugin Maven Shade](https://maven.apache.org/plugins/maven-shade-plugin/). O plugin cria um arquivo JAR que contém o código de função compilado e todas as suas dependências.

**Example pom.xml: configuração do plugin**  

```
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.2.2</version>
        <configuration>
          <createDependencyReducedPom>false</createDependencyReducedPom>
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
```

Para compilar o pacote de implantação, use o comando `mvn package`.

```
[INFO] Scanning for projects...
[INFO] -----------------------< com.example:java-maven >-----------------------
[INFO] Building java-maven-function 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
...
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ java-maven ---
[INFO] Building jar: target/java-maven-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-shade-plugin:3.2.2:shade (default) @ java-maven ---
[INFO] Including com.amazonaws:aws-lambda-java-core:jar:1.2.2 in the shaded jar.
[INFO] Including com.amazonaws:aws-lambda-java-events:jar:3.11.1 in the shaded jar.
[INFO] Including joda-time:joda-time:jar:2.6 in the shaded jar.
[INFO] Including com.google.code.gson:gson:jar:2.8.6 in the shaded jar.
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing target/java-maven-1.0-SNAPSHOT.jar with target/java-maven-1.0-SNAPSHOT-shaded.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  8.321 s
[INFO] Finished at: 2020-03-03T09:07:19Z
[INFO] ------------------------------------------------------------------------
```

Esse comando gera um arquivo JAR no diretório `target`.

**nota**  
Se você estiver trabalhando com um [JAR de várias versões (MRJAR)](https://openjdk.org/jeps/238), é necessário incluir o MRJAR (ou seja, o JAR sombreado produzido pelo plugin Maven Shade) no diretório `lib` e compactá-lo antes de fazer upload do seu pacote de implantação para o Lambda. Caso contrário, o Lambda pode não descompactar adequadamente seu arquivo JAR, fazendo com que seu arquivo `MANIFEST.MF` seja ignorado.

Se você usar a biblioteca appender (`aws-lambda-java-log4j2`), também será necessário configurar um transformador para o plugin Maven Shade. A biblioteca do transformador combina versões de um arquivo de cache que aparecem na biblioteca appender e no Log4j.

**Example pom.xml: configuração do plugin com o appender do Log4j 2**  

```
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.2.2</version>
        <configuration>
          <createDependencyReducedPom>false</createDependencyReducedPom>
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="com.github.edwgiz.maven_shade_plugin.log4j2_cache_transformer.PluginsCacheFileTransformer">
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>com.github.edwgiz</groupId>
            <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
            <version>2.13.0</version>
          </dependency>
        </dependencies>
      </plugin>
```

## Upload de um pacote de implantação com o console do Lambda
<a name="java-package-console"></a>

 Para criar uma nova função, você deve primeiro criar a função no console e depois carregar o arquivo .zip ou JAR. Para atualizar uma função existente, abra a página da função e siga o mesmo procedimento para adicionar o arquivo .zip ou JAR atualizado. 

 Se o arquivo do pacote de implantação for menor que 50 MB, você poderá criar ou atualizar uma função carregando o arquivo diretamente da máquina local. Para arquivos .zip ou JAR maiores que 50 MB, você deve primeiro carregar o pacote para um bucket do Amazon S3. Para obter instruções sobre como carregar um arquivo para um bucket do Amazon S3 usando o Console de gerenciamento da AWS, consulte [Conceitos básicos do Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html). Para carregar arquivos usando a AWS CLI, consulte [Mover objetos](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move) no *Guia do usuário da AWS CLI*. 

**nota**  
Não é possível alterar o [tipo de pacote de implantação](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-PackageType) (.zip ou imagem de contêiner) de uma função existente. Por exemplo, você não pode converter uma função de imagem de contêiner para usar um arquivo compactado .zip. É necessário criar uma nova função.

**Para criar uma função (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda e escolha **Criar função**.

1. Escolha **Author from scratch** (Criar do zero).

1. Em **Basic information** (Informações básicas), faça o seguinte:

   1. Em **Nome da função**, insira o nome da função.

   1. Em **Runtime**, selecione o runtime que você deseja usar.

   1. (Opcional) Em **Arquitetura**, escolha a arquitetura do conjunto de instruções para a função. O valor da arquitetura padrão é X86\$164. Certifique-se de que o pacote de implantação .zip da função seja compatível com a arquitetura do conjunto de instruções que você escolheu.

1. (Opcional) Em **Permissões**, expanda **Alterar função de execução padrão**. Crie uma **função de execução** ou use uma existente.

1. Escolha a opção **Criar função**. O Lambda cria uma função básica “Hello world” usando o runtime escolhido.

**Para carregar o arquivo .zip ou JAR da máquina local (console)**

1. Na [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console Lambda, escolha a função para a qual você deseja carregar o arquivo .zip ou JAR.

1. Selecione a guia **Código**.

1. No painel do **Código-fonte**, escolha **Carregar de**.

1. Escolha o **arquivo .zip ou .jar**.

1. Para carregar o arquivo .zip ou JAR, faça o seguinte:

   1. Selecione **Carregar** e, em seguida, selecione o arquivo .zip ou JAR no seletor de arquivos.

   1. Escolha **Open (Abrir)**.

   1. Escolha **Salvar**.

**Para carregar um arquivo .zip ou JAR de um bucket do Amazon S3 (console)**

1. Na [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda, escolha a função para a qual você deseja carregar um novo arquivo .zip ou JAR.

1. Selecione a guia **Código**.

1. No painel do **Código-fonte**, escolha **Carregar de**.

1. Escolha **Local do Amazon S3**.

1. Cole o URL do link do Amazon S3 do arquivo .zip e escolha **Salvar**.

## Carregar um pacote de implantação com a AWS CLI
<a name="java-package-cli"></a>

 É possível usar a [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para criar uma função ou atualizar uma existente usando um arquivo .zip ou JAR. Use os comandos [create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) e [update-function-code](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) para implantar o pacote .zip ou JAR. Se o arquivo for menor que 50 MB, você poderá carregar o pacote de um local do arquivo na máquina de compilação local. Para arquivos maiores, você deve carregar o pacote .zip ou JAR de um bucket do Amazon S3. Para obter instruções sobre como carregar um arquivo para um bucket do Amazon S3 usando a AWS CLI, consulte [Mover objetos](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move) no *Guia do usuário da AWS CLI*. 

**nota**  
Se você carregar o arquivo .zip ou JAR de um bucket do Amazon S3 usando a AWS CLI, o bucket deverá estar na mesma Região da AWS que sua função.

 Para criar uma função usando um arquivo .zip ou JAR com a AWS CLI, você deve especificar o seguinte: 
+ O nome da função (`--function-name`)
+ O runtime da função (`--runtime`)
+ O nome do recurso da Amazon (ARN) da [função de execução](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html) da função (`--role`)
+ O nome do método do manipulador no código da função (`--handler`)

 Você também deve especificar a local do arquivo .zip ou JAR. Se o arquivo .zip ou JAR estiver localizado em uma pasta da máquina de compilação local, use a opção `--zip-file` para especificar o caminho do arquivo, conforme mostrado no comando do exemplo a seguir. 

```
aws lambda create-function --function-name myFunction \
--runtime java25 --handler example.handler \
--role arn:aws:iam::123456789012:role/service-role/my-lambda-role \
--zip-file fileb://myFunction.zip
```

 Para especificar o local do arquivo .zip em um bucket do Amazon S3, use a opção `--code` conforme mostrado no comando do exemplo a seguir. Você só precisa usar o parâmetro `S3ObjectVersion` para objetos com versionamento. 

```
aws lambda create-function --function-name myFunction \
--runtime java25 --handler example.handler \
--role arn:aws:iam::123456789012:role/service-role/my-lambda-role \
--code S3Bucket=amzn-s3-demo-bucket,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion
```

 Para atualizar uma função existente usando a CLI, especifique o nome da função usando o parâmetro `--function-name`. Você também deve especificar o local do arquivo .zip que deseja usar para atualizar o código da função. Se o arquivo .zip estiver localizado em uma pasta da máquina de compilação local, use a opção `--zip-file` para especificar o caminho do arquivo, conforme mostrado no comando do exemplo a seguir. 

```
aws lambda update-function-code --function-name myFunction \
--zip-file fileb://myFunction.zip
```

 Para especificar o local do arquivo .zip em um bucket do Amazon S3, use as opções `--s3-bucket` e `--s3-key` conforme mostrado no comando do exemplo a seguir. Você só precisa usar o parâmetro `--s3-object-version` para objetos com versionamento. 

```
aws lambda update-function-code --function-name myFunction \
--s3-bucket amzn-s3-demo-bucket --s3-key myFileName.zip --s3-object-version myObject Version
```

## Fazer upload de um pacote de implantação com o AWS SAM
<a name="java-package-cloudformation"></a>

É possível usar o AWS SAM para automatizar implantações do código, da configuração e das dependências da sua função. O AWS SAM é uma extensão do CloudFormation que fornece uma sintaxe simplificada para definir aplicações sem servidor. O seguinte exemplo de modelo define uma função com um pacote de implantação no diretório `build/distributions` que o Gradle usa:

**Example template.yml**  

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Lambda application that calls the Lambda API.
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      CodeUri: build/distributions/java-basic.zip
      Handler: example.Handler
      Runtime: java25
      Description: Java function
      MemorySize: 512
      Timeout: 10
      # Function's execution role
      Policies:
        - AWSLambdaBasicExecutionRole
        - AWSLambda_ReadOnlyAccess
        - AWSXrayWriteOnlyAccess
        - AWSLambdaVPCAccessExecutionRole
      Tracing: Active
```

Para criar a função, use os comandos `package` e `deploy`. Esses comandos são personalizações para a AWS CLI. Eles envolvem outros comandos para fazer upload do pacote de implantação no Amazon S3, reescrevem o modelo com o URI do objeto e atualizam o código da função.

O exemplo de script a seguir executa uma compilação do Gradle e faz upload do pacote de implantação que ele cria. Ele cria uma pilha do CloudFormation na primeira vez que você executá-lo. Se a pilha já existir, o script a atualizará.

**Example deploy.sh**  

```
#!/bin/bash
set -eo pipefail
aws cloudformation package --template-file template.yml --s3-bucket MY_BUCKET --output-template-file out.yml
aws cloudformation deploy --template-file out.yml --stack-name java-basic --capabilities CAPABILITY_NAMED_IAM
```

Para obter um modelo funcional completo, consulte as seguintes aplicações de exemplo:

**Aplicações de exemplo do Lambda em Java**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java): uma função Java que demonstra como você pode usar o Lambda para processar pedidos. Essa função ilustra como definir e desserializar um objeto de evento de entrada personalizado, usar o AWS SDK e gerar logs de saída.
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic): uma coleção de funções Java mínimas com testes de unidade e configuração de registro em log variável.
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events): uma coleção de funções do Java contendo código básico sobre como lidar com eventos de vários serviços, como o Amazon API Gateway, o Amazon SQS e o Amazon Kinesis. Essas funções usam a versão mais recente da biblioteca [aws-lambda-java-events](#java-package) (3.0.0 e versões mais recentes). Estes exemplos não exigem o AWS SDK como dependência.
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java): uma função em Java que processa eventos de notificação do Amazon S3 e usa a Java Class Library (JCL) para criar miniaturas de arquivos de imagem enviados por upload.
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java): uma função Java que ilustra como usar uma camada do Lambda para empacotar dependências separadamente do código da função principal.

# Implantar funções do Lambda em Java com imagens de contêiner
<a name="java-image"></a>

Existem três maneiras de criar uma imagem de contêiner para uma função do Lambda em Java:
+ [Usar uma imagem base da AWS para Java](#java-image-instructions)

  As [imagens base da AWS](images-create.md#runtimes-images-lp) são pré-carregadas com um  runtime de linguagem, um cliente de interface de runtime para gerenciar a interação entre o Lambda e o código da sua função e um emulador de interface de runtime para testes locais.
+ [Usar uma imagem base somente para sistema operacional da AWS](images-create.md#runtimes-images-provided)

  [As imagens base somente para sistema operacional da AWS](https://gallery.ecr.aws/lambda/provided) contêm uma distribuição do Amazon Linux e o [emulador de interface de runtime](https://github.com/aws/aws-lambda-runtime-interface-emulator/). Essas imagens são comumente usadas para criar imagens de contêiner para linguagens compiladas, como [Go](go-image.md#go-image-provided) e [Rust](lambda-rust.md) e para uma linguagem ou versão de linguagem para a qual o Lambda não fornece uma imagem base, como Node.js 19. Também é possível usar imagens base somente para sistema operacional para implementar um [runtime personalizado](runtimes-custom.md). Para tornar a imagem compatível com o Lambda, você deve incluir [o cliente de interface de runtime do Java](#java-image-clients) na imagem.
+ [Usar uma imagem base que não é da AWS](#java-image-clients)

  Também é possível usar uma imagem base alternativa de outro registro de contêiner, como Alpine Linux ou Debian. Também é possível usar uma imagem personalizada criada por sua organização. Para tornar a imagem compatível com o Lambda, você deve incluir [o cliente de interface de runtime do Java](#java-image-clients) na imagem.

**dica**  
Para reduzir o tempo necessário para que as funções do contêiner do Lambda se tornem ativas, consulte [Use multi-stage builds](https://docs.docker.com/build/building/multi-stage/) na documentação do Docker. Para criar imagens de contêiner eficientes, siga as [Melhores práticas para gravar Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).

Esta página explica como criar, testar e implantar imagens de contêiner para o Lambda.

**Topics**
+ [Imagens base da AWS para Java](#java-image-base)
+ [Usar uma imagem base da AWS para Java](#java-image-instructions)
+ [Usar uma imagem base alternativa com o cliente da interface de runtime](#java-image-clients)

## Imagens base da AWS para Java
<a name="java-image-base"></a>

A AWS oferece as seguintes imagens base para Java:


| Tags | Runtime | Sistema operacional | Dockerfile | Desaprovação | 
| --- | --- | --- | --- | --- | 
| 25 | Java 25 | Amazon Linux 2023 | [Dockerfile para Java 25 no GitHub](https://github.com/aws/aws-lambda-base-images/blob/java25/Dockerfile.java25) |   30 de junho de 2029   | 
| 21 | Java 21 | Amazon Linux 2023 | [Dockerfile para Java 21 no GitHub](https://github.com/aws/aws-lambda-base-images/blob/java21/Dockerfile.java21) |   30 de junho de 2029   | 
| 17 | Java 17 | Amazon Linux 2 | [Dockerfile para Java 17 no GitHub](https://github.com/aws/aws-lambda-base-images/blob/java17/Dockerfile.java17) |   30º de junho de 2027   | 
| 11 | Java 11 | Amazon Linux 2 | [Dockerfile para Java 11 no GitHub](https://github.com/aws/aws-lambda-base-images/blob/java11/Dockerfile.java11) |   30º de junho de 2027   | 
| 8.al2 | Java 8 | Amazon Linux 2 | [Dockerfile para Java 8 no GitHub](https://github.com/aws/aws-lambda-base-images/blob/java8.al2/Dockerfile.java8.al2) |   30º de junho de 2027   | 

Repositório do Amazon ECR: [gallery.ecr.aws/lambda/java](https://gallery.ecr.aws/lambda/java)

As imagens base do Java 21 e posteriores são baseadas na [imagem de contêiner mínimo do Amazon Linux 2023](https://docs.aws.amazon.com/linux/al2023/ug/minimal-container.html). Imagens base anteriores usam o Amazon Linux 2. O AL2023 oferece várias vantagens em relação ao Amazon Linux 2, incluindo uma área de implantação menor e versões atualizadas de bibliotecas, como `glibc`.

As imagens baseadas no AL2023 usam o `microdnf` (com link simbólico `dnf`) como o gerenciador de pacotes, em vez do `yum`, que é o gerenciador de pacotes padrão no Amazon Linux 2. O `microdnf` é uma implementação autônoma do `dnf`. Para obter uma lista dos pacotes incluídos nas imagens baseadas no AL2023, consulte as colunas **Contêiner mínimo** em [Comparar pacotes instalados em imagens de contêiner do Amazon Linux 2023](https://docs.aws.amazon.com/linux/al2023/ug/al2023-container-image-types.html). Para obter mais informações sobre as diferenças entre o AL2023 e o Amazon Linux 2, consulte [Introdução ao runtime do Amazon Linux 2023 para AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-amazon-linux-2023-runtime-for-aws-lambda/) no blog AWS Compute.

**nota**  
Para executar imagens baseadas no AL2023 localmente, inclusive com o AWS Serverless Application Model (AWS SAM), você deve usar o Docker versão 20.10.10 ou posterior.

## Usar uma imagem base da AWS para Java
<a name="java-image-instructions"></a>

### Pré-requisitos
<a name="java-image-prerequisites"></a>

Para executar as etapas desta seção, você deve ter o seguinte:
+ Java (por exemplo, [Amazon Corretto](https://aws.amazon.com/corretto))
+ [Apache Maven](https://maven.apache.org/) ou [Gradle](https://gradle.org/install/)
+ [AWS CLI versão 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (versão mínima 25.0.0)
+ O plug-in [buildx](https://github.com/docker/buildx/blob/master/README.md) do Docker.

### Criação de uma imagem a partir de uma imagem base
<a name="java-image-create"></a>

------
#### [ Maven ]

1. Execute o comando a seguir para criar um projeto de Maven usando o [arquétipo para Lambda](https://github.com/aws/aws-sdk-java-v2/tree/master/archetypes/archetype-lambda). Os seguintes parâmetros são obrigatórios:
   + **serviço**: o cliente AWS service (Serviço da AWS) a ser usado na função do Lambda. Para obter uma lista das origens disponíveis, consulte [aws-sdk-java-v2/services](https://github.com/aws/aws-sdk-java-v2/tree/master/services) no GitHub.
   + **região**: a Região da AWS na qual você deseja criar a função do Lambda.
   + **groupId**: o namespace completo do pacote da sua aplicação.
   + **artifactId**: o nome do seu projeto. Esse será o nome do diretório do projeto.

   No Linux e no macOS, execute este comando:

   ```
   mvn -B archetype:generate \
      -DarchetypeGroupId=software.amazon.awssdk \
      -DarchetypeArtifactId=archetype-lambda -Dservice=s3 -Dregion=US_WEST_2 \
      -DgroupId=com.example.myapp \
      -DartifactId=myapp
   ```

   No PowerShell, execute este comando:

   ```
   mvn -B archetype:generate `
      "-DarchetypeGroupId=software.amazon.awssdk" `
      "-DarchetypeArtifactId=archetype-lambda" "-Dservice=s3" "-Dregion=US_WEST_2" `
      "-DgroupId=com.example.myapp" `
      "-DartifactId=myapp"
   ```

   O arquétipo do Maven para Lambda é pré-configurado para compilar com o Java SE 8 e inclui uma dependência para o AWS SDK para Java. Se você criar seu projeto com um arquétipo diferente ou usando outro método, deverá [configurar o compilador Java para Maven](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#configure-maven-compiler) e [declarar o SDK como uma dependência](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#configure-maven-compiler).

1. Abra o diretório `myapp/src/main/java/com/example/myapp` e localize o arquivo `App.java`. Este é o código da função do Lambda. É possível usar o código de exemplo fornecido para testes ou substituí-lo pelo seu.

1. Navegue de volta para o diretório raiz do projeto e, em seguida, crie um Dockerfile com a seguinte configuração:
   + Defina a propriedade `FROM` como o [URI da imagem base](https://gallery.ecr.aws/lambda/java).
   + Defina o argumento `CMD` como o manipulador de funções do Lambda.

   Observe que o Dockerfile de exemplo não inclui uma [instrução USER](https://docs.docker.com/reference/dockerfile/#user). Quando você implanta uma imagem de contêiner no Lambda, o Lambda define automaticamente um usuário padrão do Linux com permissões de privilégio mínimo. Isso é diferente do comportamento padrão do Docker, que adota o usuário `root` como padrão quando nenhuma instrução `USER` é fornecida.  
**Example Dockerfile**  

   ```
   FROM public.ecr.aws/lambda/java:21
     
   # Copy function code and runtime dependencies from Maven layout
   COPY target/classes ${LAMBDA_TASK_ROOT}
   COPY target/dependency/* ${LAMBDA_TASK_ROOT}/lib/
       
   # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
   CMD [ "com.example.myapp.App::handleRequest" ]
   ```

1. Compile o projeto e colete as dependências do runtime.

   ```
   mvn compile dependency:copy-dependencies -DincludeScope=runtime
   ```

1. Crie a imagem do Docker com o comando [docker build](https://docs.docker.com/engine/reference/commandline/build/). O exemplo a seguir nomeia a imagem como `docker-image` e atribui a ela a [tag](https://docs.docker.com/engine/reference/commandline/build/#tag) `test`. Para tornar sua imagem compatível com o Lambda, é necessário usar a opção `--provenance=false`.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**nota**  
O comando especifica a opção `--platform linux/amd64` para garantir que seu contêiner seja compatível com o ambiente de execução do Lambda, independentemente da arquitetura da sua máquina de compilação. Se você pretende criar uma função do Lambda usando a arquitetura do conjunto de instruções ARM64, certifique-se de alterar o comando para usar a opção `--platform linux/arm64` em vez disso.

------
#### [ Gradle ]

1. Crie um diretório para o projeto e depois mude para esse diretório.

   ```
   mkdir example
   cd example
   ```

1. Execute o comando a seguir para que o Gradle gere um novo projeto de aplicação Java no diretório `example` em seu ambiente. Em **Selecionar DSL de script de compilação**, escolha **2: Groovy**.

   ```
   gradle init --type java-application
   ```

1. Abra o diretório `/example/app/src/main/java/example` e localize o arquivo `App.java`. Este é o código da função  do Lambda. É possível usar o código de exemplo a seguir para fins de teste ou substituí-lo pelo seu próprio código.  
**Example App.java**  

   ```
   package com.example;
   import com.amazonaws.services.lambda.runtime.Context;
   import com.amazonaws.services.lambda.runtime.RequestHandler;
   public class App implements RequestHandler<Object, String> {
       public String handleRequest(Object input, Context context) {
           return "Hello world!";
       }
   }
   ```

1. Abra o arquivo `build.gradle`. Se você estiver usando o exemplo de código de função da etapa anterior, substitua o conteúdo de `build.gradle` pelo conteúdo a seguir. Se você estiver usando seu próprio código de função, modifique seu arquivo `build.gradle` conforme necessário.  
**Example build.gradle (DSL Groovy)**  

   ```
   plugins {
     id 'java'
   }
   group 'com.example'
   version '1.0-SNAPSHOT'
   sourceCompatibility = 1.8
   repositories {
     mavenCentral()
   }
   dependencies {
     implementation 'com.amazonaws:aws-lambda-java-core:1.2.1'
   }
   jar {
     manifest {
         attributes 'Main-Class': 'com.example.App'
     }
   }
   ```

1. O comando `gradle init` da etapa 2 também gerou um caso de teste fictício no diretório `app/test`. Para os fins deste tutorial, pule a execução de testes excluindo o diretório `/test`.

1. Crie o projeto.

   ```
   gradle build
   ```

1. No diretório raiz do projeto (`/example`), crie um Dockerfile com a seguinte configuração:
   + Defina a propriedade `FROM` como o [URI da imagem base](https://gallery.ecr.aws/lambda/java).
   + Use o comando COPY para copiar o código da função e as dependências do runtime para `{LAMBDA_TASK_ROOT}`, uma [variável de ambiente definida pelo Lambda](configuration-envvars.md#configuration-envvars-runtime).
   + Defina o argumento `CMD` como o manipulador de funções do Lambda.

   Observe que o Dockerfile de exemplo não inclui uma [instrução USER](https://docs.docker.com/reference/dockerfile/#user). Quando você implanta uma imagem de contêiner no Lambda, o Lambda define automaticamente um usuário padrão do Linux com permissões de privilégio mínimo. Isso é diferente do comportamento padrão do Docker, que adota o usuário `root` como padrão quando nenhuma instrução `USER` é fornecida.  
**Example Dockerfile**  

   ```
   FROM public.ecr.aws/lambda/java:21
     
   # Copy function code and runtime dependencies from Gradle layout
   COPY app/build/classes/java/main ${LAMBDA_TASK_ROOT}
     
   # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
   CMD [ "com.example.App::handleRequest" ]
   ```

1. Crie a imagem do Docker com o comando [docker build](https://docs.docker.com/engine/reference/commandline/build/). O exemplo a seguir nomeia a imagem como `docker-image` e atribui a ela a [tag](https://docs.docker.com/engine/reference/commandline/build/#tag) `test`. Para tornar sua imagem compatível com o Lambda, é necessário usar a opção `--provenance=false`.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**nota**  
O comando especifica a opção `--platform linux/amd64` para garantir que seu contêiner seja compatível com o ambiente de execução do Lambda, independentemente da arquitetura da sua máquina de compilação. Se você pretende criar uma função do Lambda usando a arquitetura do conjunto de instruções ARM64, certifique-se de alterar o comando para usar a opção `--platform linux/arm64` em vez disso.

------

### (Opcional) Teste a imagem localmente
<a name="java-image-test"></a>

1. Inicie a imagem do Docker com o comando **docker run**. Neste exemplo, `docker-image` é o nome da imagem e `test` é a tag.

   ```
   docker run --platform linux/amd64 -p 9000:8080 docker-image:test
   ```

   Esse comando executa a imagem como um contêiner e cria um endpoint local em `localhost:9000/2015-03-31/functions/function/invocations`.
**nota**  
Se você criou a imagem do Docker para a arquitetura do conjunto de instruções ARM64, certifique-se de usar a opção `--platform linux/arm64`, em vez de `--platform linux/amd64`.

1. Em uma nova janela de terminal, publique um evento no endpoint local.

------
#### [ Linux/macOS ]

   No Linux e no MacOS, execute o seguinte comando `curl`:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   Esse comando invoca a função com um evento vazio e retorna uma resposta. Caso esteja usando seu próprio código de função em vez do código de função de exemplo, você talvez queira invocar a função com uma carga útil JSON. Exemplo:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

------
#### [ PowerShell ]

   No PowerShell, execute o seguinte comando `Invoke-WebRequest`:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   Esse comando invoca a função com um evento vazio e retorna uma resposta. Caso esteja usando seu próprio código de função em vez do código de função de exemplo, você talvez queira invocar a função com uma carga útil JSON. Exemplo:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. Obtenha o ID do contêiner.

   ```
   docker ps
   ```

1. Use o comando [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) para parar o contêiner. Nesse comando, substitua `3766c4ab331c` pelo ID do contêiner da etapa anterior.

   ```
   docker kill 3766c4ab331c
   ```

### Implantação da imagem
<a name="java-image-deploy"></a>

**Para enviar a imagem ao Amazon ECR e criar a função do Lambda**

1. Execute o comando [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html) para autenticar a CLI do Docker no seu registro do Amazon ECR.
   + Defina o valor `--region` para a Região da AWS onde você deseja criar o repositório do Amazon ECR.
   + Substituir `111122223333` por seu ID da Conta da AWS.

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. Crie um repositório no Amazon ECR usando o comando [create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html).

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**nota**  
O repositório do Amazon ECR deve estar na mesma Região da AWS que a função do Lambda.

   Se tiver êxito, você verá uma resposta como esta:

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. Copie o `repositoryUri` da saída na etapa anterior.

1. Execute o comando [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) para aplicar uma tag na sua imagem local em seu repositório do Amazon ECR como a versão mais recente. Neste comando:
   + `docker-image:test` é o nome e a [tag](https://docs.docker.com/engine/reference/commandline/build/#tag) da sua imagem do Docker. Esse é o nome e a tag da imagem que você especificou no comando `docker build`.
   + Substitua `<ECRrepositoryUri>` pelo `repositoryUri` que você copiou. Certifique-se de incluir `:latest` no final do URI.

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   Exemplo:

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. Execute o comando [docker push](https://docs.docker.com/engine/reference/commandline/push/) para implantar a imagem local no repositório do Amazon ECR. Certifique-se de incluir `:latest` no final do URI do repositório.

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. [Crie um perfil de execução](lambda-intro-execution-role.md#permissions-executionrole-api) para a função, caso ainda não tenha um. Você precisará do nome do recurso da Amazon (ARN) do perfil na próxima etapa.

1. Criar a função do Lambda. Em `ImageUri`, especifique o URI do repositório anterior. Certifique-se de incluir `:latest` no final do URI.

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**nota**  
É possível criar uma função usando uma imagem em uma conta da AWS diferente desde que a imagem esteja na mesma região da função do Lambda. Para obter mais informações, consulte [Permissões entre contas do Amazon ECR](images-create.md#configuration-images-xaccount-permissions).

1. Invoque a função.

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   Você obterá uma resposta parecida com esta:

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. Para ver a saída da função, verifique o arquivo `response.json`.

Para atualizar o código da função, você deve criar a imagem novamente, fazer upload da nova imagem no repositório do Amazon ECR e, em seguida, usar o comando [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) para implantar a imagem na função do Lambda.

O Lambda resolve a tag de imagem em um resumo de imagem específico. Isso significa que, se você apontar a tag de imagem que foi usada para implantar a função em uma nova imagem no Amazon ECR, o Lambda não atualizará automaticamente a função para usar a nova imagem.

Para implantar a nova imagem na mesma função do Lambda, você deverá usar o comando [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html), mesmo que a tag da imagem no Amazon ECR permaneça a mesma. No exemplo a seguir, a opção `--publish` cria uma nova versão da função usando a imagem de contêiner atualizada.

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

## Usar uma imagem base alternativa com o cliente da interface de runtime
<a name="java-image-clients"></a>

Se você usar uma [imagem base somente para sistema operacional](images-create.md#runtimes-images-provided) ou uma imagem base alternativa, deverá incluir o cliente de interface de runtime na imagem. O cliente de interface de runtime estende [API de runtime](runtimes-api.md), que gerencia a interação entre o Lambda e o código da sua função.

Instale o cliente de interface de runtime para Java no Dockerfile ou como uma dependência no projeto. Por exemplo, para instalar o cliente de interface de runtime usando o gerenciador de pacotes Maven, adicione o seguinte ao seu arquivo `pom.xml`:

```
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-runtime-interface-client</artifactId>
    <version>2.3.2</version>
</dependency>
```

Para obter detalhes do pacote, consulte [Cliente de interface de runtime do AWS Lambda em Java](https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-runtime-interface-client) no Repositório central do Maven. Também é possível revisar o código-fonte do cliente de interface de runtime no repositório de [Bibliotecas de suporte do Java do AWS Lambda](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-runtime-interface-client) no GitHub.

O exemplo a seguir demonstra como criar uma imagem de contêiner para Java usando uma [imagem do Amazon Corretto](https://gallery.ecr.aws/amazoncorretto/amazoncorretto). O Amazon Corretto é uma distribuição gratuita, multiplataforma e pronta para produção do Open Java Development Kit (OpenJDK). O projeto do Maven inclui o cliente de interface de runtime como uma dependência.

### Pré-requisitos
<a name="java-alt-prerequisites"></a>

Para executar as etapas desta seção, você deve ter o seguinte:
+ Java (por exemplo, [Amazon Corretto](https://aws.amazon.com/corretto))
+ [Apache Maven](https://maven.apache.org/)
+ [AWS CLI versão 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (versão mínima 25.0.0)
+ O plug-in [buildx](https://github.com/docker/buildx/blob/master/README.md) do Docker.

### Criar uma imagem de uma imagem base alternativa
<a name="java-alt-create"></a>

1. Criar um projeto do Maven. Os seguintes parâmetros são obrigatórios:
   + **groupId**: o namespace completo do pacote da sua aplicação.
   + **artifactId**: o nome do seu projeto. Esse será o nome do diretório do projeto.

------
#### [ Linux/macOS ]

   ```
   mvn -B archetype:generate \
      -DarchetypeArtifactId=maven-archetype-quickstart \
      -DgroupId=example \
      -DartifactId=myapp \
      -DinteractiveMode=false
   ```

------
#### [ PowerShell ]

   ```
   mvn -B archetype:generate `
      -DarchetypeArtifactId=maven-archetype-quickstart `
      -DgroupId=example `
      -DartifactId=myapp `
      -DinteractiveMode=false
   ```

------

1. Abra o diretório do projeto.

   ```
   cd myapp
   ```

1. Abra o arquivo `pom.xml` e substitua o conteúdo pelo seguinte. Esse arquivo inclui o [aws-lambda-java-runtime-interface-client](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-runtime-interface-client) como uma dependência. Como alternativa, você também pode instalar o cliente de interface de runtime no Dockerfile. No entanto, a abordagem mais simples é incluir a biblioteca como uma dependência.

   ```
   <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>example</groupId>
     <artifactId>hello-lambda</artifactId>
     <packaging>jar</packaging>
     <version>1.0-SNAPSHOT</version>
     <name>hello-lambda</name>
     <url>http://maven.apache.org</url>
     <properties>
       <maven.compiler.source>1.8</maven.compiler.source>
       <maven.compiler.target>1.8</maven.compiler.target>
     </properties>
     <dependencies>
       <dependency>
         <groupId>com.amazonaws</groupId>
         <artifactId>aws-lambda-java-runtime-interface-client</artifactId>
         <version>2.3.2</version>
       </dependency>
     </dependencies>
     <build>
       <plugins>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-dependency-plugin</artifactId>
           <version>3.1.2</version>
           <executions>
             <execution>
               <id>copy-dependencies</id>
               <phase>package</phase>
               <goals>
                 <goal>copy-dependencies</goal>
               </goals>
             </execution>
           </executions>
         </plugin>
       </plugins>
     </build>
   </project>
   ```

1. Abra o diretório `myapp/src/main/java/com/example/myapp` e localize o arquivo `App.java`. Este é o código da função do Lambda. Substitua o código pelo seguinte.  
**Example manipulador de função**  

   ```
   package example;
   
   public class App {
       public static String sayHello() {
           return "Hello world!";
       }
   }
   ```

1. O comando `mvn -B archetype:generate` da etapa 1 também gerou um caso de teste fictício no diretório `src/test`. Para fins deste tutorial, pule a execução de testes excluindo todo este diretório `/test` gerado.

1. Navegue de volta para o diretório raiz do projeto e, em seguida, crie um Dockerfile. O Dockerfile do exemplo a seguir usa uma [imagem do Amazon Corretto](https://gallery.ecr.aws/amazoncorretto/amazoncorretto). O Amazon Corretto é uma distribuição gratuita, multiplataforma e pronta para produção do OpenJDK.
   + Defina a propriedade `FROM` como o URI da imagem base.
   + Defina o `ENTRYPOINT` como o módulo em que você deseja que o contêiner do Docker seja executado quando for iniciado. Nesse caso, o módulo é o cliente de interface de runtime.
   + Defina o argumento `CMD` como o manipulador de funções do Lambda.

   Observe que o Dockerfile de exemplo não inclui uma [instrução USER](https://docs.docker.com/reference/dockerfile/#user). Quando você implanta uma imagem de contêiner no Lambda, o Lambda define automaticamente um usuário padrão do Linux com permissões de privilégio mínimo. Isso é diferente do comportamento padrão do Docker, que adota o usuário `root` como padrão quando nenhuma instrução `USER` é fornecida.  
**Example Dockerfile**  

   ```
   FROM public.ecr.aws/amazoncorretto/amazoncorretto:21 as base
   
   # Configure the build environment
   FROM base as build
   RUN yum install -y maven
   WORKDIR /src
   
   # Cache and copy dependencies
   ADD pom.xml .
   RUN mvn dependency:go-offline dependency:copy-dependencies
   
   # Compile the function
   ADD . .
   RUN mvn package 
   
   # Copy the function artifact and dependencies onto a clean base
   FROM base
   WORKDIR /function
   
   COPY --from=build /src/target/dependency/*.jar ./
   COPY --from=build /src/target/*.jar ./
   
   # Set runtime interface client as default command for the container runtime
   ENTRYPOINT [ "/usr/bin/java", "-cp", "./*", "com.amazonaws.services.lambda.runtime.api.client.AWSLambda" ]
   # Pass the name of the function handler as an argument to the runtime
   CMD [ "example.App::sayHello" ]
   ```

1. Crie a imagem do Docker com o comando [docker build](https://docs.docker.com/engine/reference/commandline/build/). O exemplo a seguir nomeia a imagem como `docker-image` e atribui a ela a [tag](https://docs.docker.com/engine/reference/commandline/build/#tag) `test`. Para tornar sua imagem compatível com o Lambda, é necessário usar a opção `--provenance=false`.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**nota**  
O comando especifica a opção `--platform linux/amd64` para garantir que seu contêiner seja compatível com o ambiente de execução do Lambda, independentemente da arquitetura da sua máquina de compilação. Se você pretende criar uma função do Lambda usando a arquitetura do conjunto de instruções ARM64, certifique-se de alterar o comando para usar a opção `--platform linux/arm64` em vez disso.

### (Opcional) Teste a imagem localmente
<a name="java-alt-test"></a>

Use o [emulador de interface de runtime](https://github.com/aws/aws-lambda-runtime-interface-emulator/) para testar a imagem localmente. É possível [compilar o emulador em sua imagem](https://github.com/aws/aws-lambda-runtime-interface-emulator/?tab=readme-ov-file#build-rie-into-your-base-image) ou usar o procedimento a seguir instalá-lo na sua máquina local.

**Para instalar o emulador de interface de runtime na sua máquina local**

1. No diretório do projeto, execute o comando a seguir para baixar o emulador de interface de runtime (arquitetura x86-64) do GitHub e instalá-lo na sua máquina local.

------
#### [ Linux/macOS ]

   ```
   mkdir -p ~/.aws-lambda-rie && \
       curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \
       chmod +x ~/.aws-lambda-rie/aws-lambda-rie
   ```

   Para instalar o emulador arm64, substitua o URL do repositório do GitHub no comando anterior pelo seguinte:

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------
#### [ PowerShell ]

   ```
   $dirPath = "$HOME\.aws-lambda-rie"
   if (-not (Test-Path $dirPath)) {
       New-Item -Path $dirPath -ItemType Directory
   }
         
   $downloadLink = "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie"
   $destinationPath = "$HOME\.aws-lambda-rie\aws-lambda-rie"
   Invoke-WebRequest -Uri $downloadLink -OutFile $destinationPath
   ```

   Para instalar o emulador de arm64, substitua `$downloadLink` pelo seguinte:

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------

1. Inicie a imagem do Docker com o comando **docker run**. Observe o seguinte:
   + `docker-image` é o nome da imagem e `test` é a tag.
   + `/usr/bin/java -cp './*' com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App::sayHello` é o `ENTRYPOINT` seguido pelo `CMD` do Dockerfile.

------
#### [ Linux/macOS ]

   ```
   docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
       --entrypoint /aws-lambda/aws-lambda-rie \
       docker-image:test \
           /usr/bin/java -cp './*' com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App::sayHello
   ```

------
#### [ PowerShell ]

   ```
   docker run --platform linux/amd64 -d -v "$HOME\.aws-lambda-rie:/aws-lambda" -p 9000:8080 `
   --entrypoint /aws-lambda/aws-lambda-rie `
   docker-image:test `
       /usr/bin/java -cp './*' com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App::sayHello
   ```

------

   Esse comando executa a imagem como um contêiner e cria um endpoint local em `localhost:9000/2015-03-31/functions/function/invocations`.
**nota**  
Se você criou a imagem do Docker para a arquitetura do conjunto de instruções ARM64, certifique-se de usar a opção `--platform linux/arm64`, em vez de `--platform linux/amd64`.

1. Publique um evento no endpoint local.

------
#### [ Linux/macOS ]

   No Linux e no MacOS, execute o seguinte comando `curl`:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   Esse comando invoca a função com um evento vazio e retorna uma resposta. Caso esteja usando seu próprio código de função em vez do código de função de exemplo, você talvez queira invocar a função com uma carga útil JSON. Exemplo:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

------
#### [ PowerShell ]

   No PowerShell, execute o seguinte comando `Invoke-WebRequest`:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   Esse comando invoca a função com um evento vazio e retorna uma resposta. Caso esteja usando seu próprio código de função em vez do código de função de exemplo, você talvez queira invocar a função com uma carga útil JSON. Exemplo:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. Obtenha o ID do contêiner.

   ```
   docker ps
   ```

1. Use o comando [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) para parar o contêiner. Nesse comando, substitua `3766c4ab331c` pelo ID do contêiner da etapa anterior.

   ```
   docker kill 3766c4ab331c
   ```

### Implantação da imagem
<a name="java-alt-deploy"></a>

**Para enviar a imagem ao Amazon ECR e criar a função do Lambda**

1. Execute o comando [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html) para autenticar a CLI do Docker no seu registro do Amazon ECR.
   + Defina o valor `--region` para a Região da AWS onde você deseja criar o repositório do Amazon ECR.
   + Substituir `111122223333` por seu ID da Conta da AWS.

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. Crie um repositório no Amazon ECR usando o comando [create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html).

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**nota**  
O repositório do Amazon ECR deve estar na mesma Região da AWS que a função do Lambda.

   Se tiver êxito, você verá uma resposta como esta:

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. Copie o `repositoryUri` da saída na etapa anterior.

1. Execute o comando [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) para aplicar uma tag na sua imagem local em seu repositório do Amazon ECR como a versão mais recente. Neste comando:
   + `docker-image:test` é o nome e a [tag](https://docs.docker.com/engine/reference/commandline/build/#tag) da sua imagem do Docker. Esse é o nome e a tag da imagem que você especificou no comando `docker build`.
   + Substitua `<ECRrepositoryUri>` pelo `repositoryUri` que você copiou. Certifique-se de incluir `:latest` no final do URI.

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   Exemplo:

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. Execute o comando [docker push](https://docs.docker.com/engine/reference/commandline/push/) para implantar a imagem local no repositório do Amazon ECR. Certifique-se de incluir `:latest` no final do URI do repositório.

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. [Crie um perfil de execução](lambda-intro-execution-role.md#permissions-executionrole-api) para a função, caso ainda não tenha um. Você precisará do nome do recurso da Amazon (ARN) do perfil na próxima etapa.

1. Criar a função do Lambda. Em `ImageUri`, especifique o URI do repositório anterior. Certifique-se de incluir `:latest` no final do URI.

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**nota**  
É possível criar uma função usando uma imagem em uma conta da AWS diferente desde que a imagem esteja na mesma região da função do Lambda. Para obter mais informações, consulte [Permissões entre contas do Amazon ECR](images-create.md#configuration-images-xaccount-permissions).

1. Invoque a função.

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   Você obterá uma resposta parecida com esta:

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. Para ver a saída da função, verifique o arquivo `response.json`.

Para atualizar o código da função, você deve criar a imagem novamente, fazer upload da nova imagem no repositório do Amazon ECR e, em seguida, usar o comando [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) para implantar a imagem na função do Lambda.

O Lambda resolve a tag de imagem em um resumo de imagem específico. Isso significa que, se você apontar a tag de imagem que foi usada para implantar a função em uma nova imagem no Amazon ECR, o Lambda não atualizará automaticamente a função para usar a nova imagem.

Para implantar a nova imagem na mesma função do Lambda, você deverá usar o comando [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html), mesmo que a tag da imagem no Amazon ECR permaneça a mesma. No exemplo a seguir, a opção `--publish` cria uma nova versão da função usando a imagem de contêiner atualizada.

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

# Como trabalhar com camadas para funções do Lambda em Java
<a name="java-layers"></a>

Use [camadas do Lambda](chapter-layers.md) para empacotar o código e as dependências que você quiser reutilizar em várias funções. As camadas geralmente contêm dependências de biblioteca, um [runtime personalizado](runtimes-custom.md) ou arquivos de configuração. A criação de uma camada envolve três etapas gerais:

1. Empacotar o conteúdo da sua camada. Isso significa criar um arquivo .zip contendo as dependências que você deseja usar em suas funções.

1. Criar a camada no Lambda.

1. Adicionar a camada às suas funções.

**Topics**
+ [Empacotar o conteúdo da sua camada](#java-layers-package)
+ [Criar a camada no Lambda](#publishing-layer)
+ [Adicionar a camada à função](#java-layer-adding)

## Empacotar o conteúdo da sua camada
<a name="java-layers-package"></a>

Para criar uma camada, reúna os pacotes em um arquivo .zip que atenda aos seguintes requisitos:
+ Certifique-se de que a versão Java à qual o Maven ou Gradle se refere seja a mesma versão Java da função que você pretende implantar. Por exemplo, para uma função em Java 25, o comando `mvn -v` deverá listar o Java 25 na saída.
+ Suas dependências devem ser armazenadas no diretório `java/lib`, na raiz do arquivo .zip. Para obter mais informações, consulte [Caminhos da camada para cada runtime do Lambda](packaging-layers.md#packaging-layers-paths).
+ Os pacotes da camada devem ser compatíveis com o Linux. As funções do Lambda são executadas no Amazon Linux.

Você pode criar camadas que contenham bibliotecas Java de terceiros ou seus próprios módulos e pacotes Java. O procedimento a seguir utiliza o Maven. Também é possível utilizar o Gradle para empacotar o conteúdo da camada.

**Para criar uma camada com dependências do Maven**

1. Crie um projeto Apache Maven com um arquivo `pom.xml` que defina suas dependências.

   O exemplo abaixo inclui [Jackson Databind](https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind) para processamento JSON. A seção `<build>` usa [maven-dependency-plugin](https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-dependency-plugin) para criar arquivos JAR distintos para cada dependência, em vez de os agrupar em um único uber-jar. Se quiser criar um uber-jar, use [maven-shade-plugin](https://maven.apache.org/plugins/maven-shade-plugin/).  
**Example pom.xml**  

   ```
   <dependencies>
       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-databind</artifactId>
           <version>2.17.0</version>
       </dependency>
   </dependencies>
   
   <build>
       <plugins>
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-compiler-plugin</artifactId>
               <version>3.13.0</version>
               <configuration>
                   <source>21</source>
                   <target>21</target>
                   <release>21</release>
               </configuration>
           </plugin>
           
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-dependency-plugin</artifactId>
               <version>3.6.1</version>
               <executions>
                   <execution>
                       <id>copy-dependencies</id>
                       <phase>package</phase>
                       <goals>
                           <goal>copy-dependencies</goal>
                       </goals>
                       <configuration>
                           <outputDirectory>${project.build.directory}/lib</outputDirectory>
                       </configuration>
                   </execution>
               </executions>
           </plugin>
       </plugins>
   </build>
   ```

1. Crie o projeto. Esse comando cria todos os arquivos JAR de dependência no diretório `target/lib/`.

   ```
   mvn clean package
   ```

1. Crie a estrutura de diretório necessária para sua camada:

   ```
   mkdir -p java/lib
   ```

1. Copie os arquivos JAR de dependências para o diretório `java/lib`:

   ```
   cp target/lib/*.jar java/lib/
   ```

1. Crie um arquivo .zip do conteúdo da camada:

------
#### [ Linux/macOS ]

   ```
   zip -r layer.zip java/
   ```

------
#### [ PowerShell ]

   ```
   Compress-Archive -Path .\java -DestinationPath .\layer.zip
   ```

------

   A estrutura de diretórios do arquivo zip deve ser assim:

   ```
   java/              
   └── lib/
       ├── jackson-databind-2.17.0.jar
       ├── jackson-core-2.17.0.jar
       └── jackson-annotations-2.17.0.jar
   ```
**nota**  
Garanta que o arquivo .zip inclua o diretório `java` no nível raiz com `lib` dentro dele. Essa estrutura garante que o Lambda consiga localizar e importar suas bibliotecas. Cada dependência é mantida como um arquivo JAR distinto, em vez de serem agrupadas em um uber-jar.

## Criar a camada no Lambda
<a name="publishing-layer"></a>

Você pode publicar a camada usando a AWS CLI ou o console do Lambda.

------
#### [ AWS CLI ]

Execute o comando da AWS CLI [publish-layer-version](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/publish-layer-version.html) para criar a camada do Lambda:

```
aws lambda publish-layer-version --layer-name my-layer --zip-file fileb://layer.zip --compatible-runtimes java25
```

O parâmetro [runtimes compatíveis](https://docs.aws.amazon.com/lambda/latest/api/API_PublishLayerVersion.html#lambda-PublishLayerVersion-request-CompatibleRuntimes) é opcional. Quando especificado, o Lambda usa esse parâmetro para filtrar camadas no console do Lambda.

------
#### [ Console ]

**Para criar uma camada (console)**

1. Abra a [página Layers](https://console.aws.amazon.com/lambda/home#/layers) (Camadas) do console do Lambda.

1. Escolha **Criar camada**.

1. Escolha **Carregar um arquivo .zip** e depois carregue o arquivo .zip que você criou anteriormente.

1. (Opcional) Para ver quais são os **runtimes compatíveis**, escolha o runtime Java que corresponde à versão do Java que você usou para criar a camada.

1. Escolha **Criar**.

------

## Adicionar a camada à função
<a name="java-layer-adding"></a>

------
#### [ AWS CLI ]

Para anexar a camada à função, execute o comando da AWS CLI [update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) . Para o parâmetro `--layers` use o ARN da camada. O ARN deve especificar a versão (por exemplo, `arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1`). Para obter mais informações, consulte [Camadas e versões da camada](chapter-layers.md#lambda-layer-versions).

```
aws lambda update-function-configuration --function-name my-function --cli-binary-format raw-in-base64-out --layers "arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1"
```

A opção **cli-binary-format** será necessária se você estiver usando a AWS CLI versão 2. Para que essa seja a configuração padrão, execute `aws configure set cli-binary-format raw-in-base64-out`. Para obter mais informações, consulte [A AWS CLI comporta opções de linha de comando globais](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) no *Guia do usuário da AWS Command Line Interface versão 2*.

------
#### [ Console ]

**Para adicionar uma camada a uma função**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha a função.

1. Role a tela para baixo até a seção **Camadas** e depois escolha **Adicionar uma camada**.

1. Em **Escolher uma camada**, selecione **Camadas personalizadas** e depois escolha a camada.
**nota**  
Se você não adicionou um [runtime compatível](https://docs.aws.amazon.com/lambda/latest/api/API_PublishLayerVersion.html#lambda-PublishLayerVersion-request-CompatibleRuntimes) ao criar a camada, ela não estará listada aqui. Em vez disso, você pode especificar o ARN da camada.

1. Escolha **Adicionar**.

------

# Personalização da serialização para funções do Lambda em Java
<a name="java-custom-serialization"></a>

Os [runtimes gerenciados para Java](lambda-java.md#java-runtimes) do Lambda oferecem suporte para a serialização personalizada para eventos JSON. A serialização personalizada pode simplificar o código e, potencialmente, aumentar a performance.

**Topics**
+ [Quando usar serialização personalizada](#custom-serialization-use-cases)
+ [Implementação de serialização personalizada](#implement-custom-serialization)
+ [Teste da serialização personalizada](#test-custom-serialization)

## Quando usar serialização personalizada
<a name="custom-serialization-use-cases"></a>

Quando a função do Lambda é invocada, os dados do evento de entrada precisam passar pela desserialização em um objeto em Java, e a saída da função precisa ser serializada novamente em um formato que possa ser retornado como resposta da função. Os runtimes gerenciados do Lambda para Java fornecem funcionalidades de serialização e desserialização padrão que funcionam bem para lidar com cargas úteis de eventos de vários serviços da AWS, como o Amazon API Gateway e o Amazon Simple Queue Service (Amazon SQS). Para trabalhar com esses eventos de integração de serviços em sua função, adicione a dependência [aws-java-lambda-events](https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-events) ao seu projeto. Esta biblioteca da AWS contém objetos em Java que representam esses eventos de integração de serviços.

Você também pode usar seus próprios objetos para representar o JSON do evento que você fornece para a função do Lambda. O runtime gerenciado tenta serializar o JSON para uma nova instância do objeto com o comportamento padrão. Se o serializador padrão não apresentar o comportamento desejado para o seu caso de uso, utilize a serialização personalizada.

Por exemplo, suponha que o manipulador da sua função espera uma classe `Vehicle` como entrada, com a seguinte estrutura:

```
public class Vehicle {
    private String vehicleType;
    private long vehicleId;
}
```

No entanto, a carga útil do evento JSON é semelhante a:

```
{
    "vehicle-type": "car",
    "vehicleID": 123
}
```

Neste caso, a serialização padrão no runtime gerenciado requer que os nomes das propriedades em JSON coincidam com os nomes das propriedades da classe Java em camel case (`vehicleType` e `vehicleId`). Como os nomes das propriedades no evento JSON não estão em camel case (`vehicle-type` e `vehicleID`), é necessário usar a serialização personalizada.

## Implementação de serialização personalizada
<a name="implement-custom-serialization"></a>

Faça uso de uma [interface de provedor de serviços](https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html) para carregar um serializador de sua preferência, em vez de usar a lógica de serialização padrão do runtime gerenciado. É possível serializar as cargas úteis dos eventos JSON diretamente em objetos em Java ao usar a interface `RequestHandler` padrão.

**Para usar a serialização personalizada em sua função do Lambda em Java**

1. Adicione a biblioteca [aws-lambda-java-core](https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-core) como uma dependência. Esta biblioteca inclui a interface [CustomPojoSerializer](https://github.com/aws/aws-lambda-java-libs/blob/main/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/CustomPojoSerializer.java), juntamente com outras definições de interface para o uso com o Java no Lambda.

1. Crie um arquivo chamado `com.amazonaws.services.lambda.runtime.CustomPojoSerializer` no diretório `src/main/resources/META-INF/services/` do seu projeto.

1. Neste arquivo, especifique o nome totalmente qualificado da implementação de serializador personalizada, que deve implementar a interface `CustomPojoSerializer`. Exemplo:

   ```
   com.mycompany.vehicles.CustomLambdaSerialzer
   ```

1. Implemente a interface `CustomPojoSerializer` para fornecer sua lógica de serialização personalizada.

1. Use a interface `RequestHandler` padrão em sua função do Lambda. O runtime gerenciado usará o serializador personalizado.

Para obter mais exemplos de como implementar a serialização personalizada usando bibliotecas populares como fastJson, Gson, Moshi e jackson-jr, consulte o exemplo [custom-serialization](https://github.com/aws/aws-lambda-java-libs/tree/main/samples/custom-serialization) no repositório GitHub da AWS.

## Teste da serialização personalizada
<a name="test-custom-serialization"></a>

Teste sua função para garantir que sua lógica de serialização e desserialização esteja funcionando conforme o esperado. É possível usar a AWS Serverless Application Model Command Line Interface (AWS SAM CLI) para emular a invocação da carga útil da função do Lambda. Isso ajuda a testar e iterar rapidamente em sua função à medida que você implementa um serializador personalizado.

1. Crie um arquivo com a carga útil do evento JSON que você deseja usar para invocar a função e, em seguida, chame a AWS SAM CLI.

1. Execute o comando [sam local invoke](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html ) para invocar sua função localmente. Exemplo:

   ```
   sam local invoke -e src/test/resources/event.json
   ```

Para obter mais informações, consulte [Locally invoke Lambda functions with AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-invoke.html).

# Personalizar o comportamento de startup de runtime para as funções do Lambda
<a name="java-customization"></a>

Esta página descreve as configurações específicas das funções  do Java no AWS Lambda. É possível usar essas configurações para personalizar o comportamento de inicialização de runtime do Java. Isso pode reduzir a latência geral da função e melhorar a  performance geral da função sem a necessidade de modificar  qualquer código.

**Topics**
+ [Entender a variável de ambiente `JAVA_TOOL_OPTIONS`](#java-tool-options)
+ [Patch do Log4j para o Log4Shell](#log4shell-patch)
+ [Caches antecipados (AOT) e CDS](#aot-cds-caches)

## Entender a variável de ambiente `JAVA_TOOL_OPTIONS`
<a name="java-tool-options"></a>

No Java, o Lambda é compatível com a variável de ambiente `JAVA_TOOL_OPTIONS` para definir variáveis adicionais da linha de comando no Lambda. É possível usar essa variável de ambiente de várias maneiras, como para personalizar configurações de compilação em camadas. O exemplo a seguir demonstra como usar a variável de ambiente `JAVA_TOOL_OPTIONS` para esse caso de uso.

### Exemplo: personalizar as configurações de compilação em camadas
<a name="tiered-compilation"></a>

A compilação em camadas é um recurso da máquina virtual Java (JVM). É possível usar configurações específicas de compilação em camadas para fazer o melhor uso dos compiladores just-in-time (JIT) da JVM. Normalmente, o compilador C1 é otimizado para um tempo de inicialização rápido. O compilador C2 é otimizado para a melhor performance geral, mas também usa mais memória e leva mais tempo para alcançá-la. Existem cinco níveis diferentes de compilação em camadas. No nível 0, a JVM interpreta o código de bytes do Java. No nível 4, a JVM usa o compilador C2 para analisar os dados de criação de perfil coletados durante a inicialização da aplicação. Com o tempo, ele monitora o uso do código para identificar as melhores otimizações.

Personalização do nível de compilação em camadas pode ajudar a ajustar a performance da sua função do Java. Para funções pequenas que são executadas rapidamente, definir a compilação em camadas para o nível 1 pode ajudar a melhorar a performance da inicialização a frio fazendo com que a JVM use o compilador C1. Essa configuração produz rapidamente código nativo otimizado, mas não gera qualquer dado de criação de perfil e nunca usa o compilador C2. Para funções maiores e computacionalmente intensivas, definir a compilação em camadas para o nível 4 maximiza a performance geral às custas de consumo adicional de memória e de trabalho adicional de otimização durante as primeiras invocações após o provisionamento de cada ambiente de execução do Lambda.

Para runtimes do Java 11 e versões anteriores, o Lambda usa as configurações padrão de compilação em camadas da JVM. Por padrão, para o Java 17 e o Java 21, o Lambda configura a JVM para interromper a compilação em camadas no nível 1. A partir do Java 25, o Lambda ainda interrompe a compilação em camadas no nível 1 por padrão, exceto ao usar o SnapStart ou a simultaneidade provisionada, caso em que as configurações padrão da JVM são usadas. Isso melhora a performance do SnapStart e da simultaneidade provisionada sem incorrer em uma penalidade de inicialização a frio, já que a compilação hierárquica é realizada fora do caminho de chamada nesses casos. Para maximizar esse benefício, é possível usar caminhos de código de execução primária durante a inicialização da função para acionar o JIT antes de tirar o snapshot do SnapStart ou quando os ambientes de execução de simultaneidade provisionada são pré-provisionados. Para obter mais informações, consulte a postagem do blog [Otimização daperformance da inicialização a frio do AWS Lambda com o uso de estratégias avançadas de preparação com o SnapStart](https://aws.amazon.com/blogs/compute/optimizing-cold-start-performance-of-aws-lambda-using-advanced-priming-strategies-with-snapstart/).

**Para personalizar as configurações de compilação em camadas (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) no console do Lambda.

1. Escolha uma função do Java para a qual você deseja personalizar a compilação em camadas.

1. Escolha a guia **Configuração** e, em seguida, escolha **Variáveis de ambiente** no menu à esquerda.

1. Selecione a opção **Editar**.

1. Escolha **Add environment variable (Adicionar variável de ambiente)**.

1.  Na chave, insira `JAVA_TOOL_OPTIONS`. No valor, insira `-XX:+TieredCompilation -XX:TieredStopAtLevel=1`.   
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/java-tool-options-tiered-compilation.png)

1. Escolha **Salvar**.

**nota**  
Também é possível usar o Lambda SnapStart para mitigar problemas de inicialização a frio. O SnapStart usa snapshots em cache do ambiente de execução para melhorar significativamente a performance da inicialização. Para obter mais informações sobre os recursos, limitações e regiões compatíveis com o SnapStart, consulte [Aprimoramento da performance de inicialização com o Lambda SnapStart](snapstart.md).

### Exemplo: personalização do comportamento do GC usando JAVA\$1TOOL\$1OPTIONS
<a name="gc-behavior"></a>

Os runtimes do Java 11 usam o [Serial](https://docs.oracle.com/en/java/javase/18/gctuning/available-collectors.html#GUID-45794DA6-AB96-4856-A96D-FDE5F7DEE498) garbage collector (GC) para a coleta de resíduos. Por padrão, os runtimes do Java 17 também usam o Serial GC. No entanto, com o Java 17, você também pode usar a variável de ambiente `JAVA_TOOL_OPTIONS` para alterar o GC padrão. É possível escolher entre o Parallel GC e o [Shenandoah GC](https://wiki.openjdk.org/display/shenandoah/Main).

Por exemplo, se sua workload usa mais memória e diversas CPUs, considere usar o Parallel GC para obter melhor performance. É possível fazer isso ao anexar o seguinte ao valor da variável de ambiente `JAVA_TOOL_OPTIONS`:

```
-XX:+UseParallelGC
```

Se a sua workload tiver muitos objetos de curta duração, será possível se beneficiar de menor consumo de memória ativando o modo geracional do coletor de lixo Shenandoah introduzido no Java 25. Para fazer isso, anexe o valor a seguir ao valor da variável de ambiente `JAVA_TOOL_OPTIONS`:

```
-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational
```

## Patch do Log4j para o Log4Shell
<a name="log4shell-patch"></a>

Os runtimes do Lambda para Java 8, 11, 17 e 21 incluem um patch para mitigar a vulnerabilidade do Log4Shell (CVE-2021-44228) no Log4j, uma estrutura popular de registro em log em Java. Esse patch gera uma sobrecarga de performance na inicialização a frio. Se você estiver usando uma versão corrigida do Log4j (versão 2.17.0 ou posterior), é possível desabilitar esse patch para melhorar a performance da inicialização a frio. Para desabilitar esse aviso, defina a variável de ambiente `AWS_LAMBDA_DISABLE_CVE_2021_44228_PROTECTION` como `true`.

A partir do Java 25, os runtimes do Lambda não incluem mais o patch Log4Shell. É necessário verificar se você está usando o Log4j versão 2.17.0 ou posterior.

## Caches antecipados (AOT) e CDS
<a name="aot-cds-caches"></a>

A partir do Java 25, o runtime do Lambda inclui um cache antecipado (AOT) para o cliente de interface de runtime Java (RIC), um componente de runtime que sonda ativamente os eventos da API de runtime do Lambda. Isso melhora a performance da inicialização a frio.

Os caches AOT são específicos para uma compilação da JVM. Quando o Lambda atualiza o runtime gerenciado, ele também atualiza o cache AOT para o RIC. No entanto, se você implantar seus próprios caches AOT, eles poderão ser invalidados ou resultar em um comportamento inesperado após uma atualização de runtime. Portanto, é altamente recomendável não usar caches AOT ao usar runtimes gerenciados. Para usar caches AOT, você deve implantar suas funções usando imagens de contêiner.

Os caches AOT não podem ser usados com os caches de compartilhamento de dados de classe (CDS). Se você implantar caches de CDS em sua função do Lambda, o Lambda desabilitará o cache AOT.

# Usar o objeto de contexto do Lambda para recuperar informações das funções em Java
<a name="java-context"></a>

Quando o Lambda executa a função, ele transmite um objeto de contexto para o [handler](java-handler.md). Esse objeto fornece métodos e propriedades que fornecem informações sobre a invocação, a função e o ambiente de execução.

**Métodos de contexto**
+ `getRemainingTimeInMillis()`— Retorna o número de milissegundos restantes antes do tempo limite da execução.
+ `getFunctionName()`: retorna o nome da função do Lambda.
+ `getFunctionVersion()`— Retorna o[version](configuration-versions.md)da função do.
+ `getInvokedFunctionArn()`: retorna o nome do recurso da Amazon (ARN) usado para invocar a função. Indica se o invocador especificou um número de versão ou alias.
+ `getMemoryLimitInMB()`— Retorna a quantidade de memória alocada para a função.
+ `getAwsRequestId()`— Retorna o identificador de invocação da solicitação.
+ `getLogGroupName()`— Retorna o grupo de logs para a função do.
+ `getLogStreamName()`— Retorna o stream de log para a instância da função.
+ `getIdentity()`— (aplicativos móveis) Retorna informações sobre a identidade do Amazon Cognito que autorizou a solicitação.
+ `getClientContext()`— (aplicativos móveis) Retorna o contexto do cliente que é fornecido ao Lambda pelo aplicativo cliente.
+ `getLogger()`: retorna o [objeto logger](java-logging.md) para a função.

O exemplo a seguir mostra uma função que usa o objeto de contexto para acessar o logger do Lambda.

**Example [Handler.java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic/src/main/java/example/Handler.java)**  

```
package example;

import [com.amazonaws.services.lambda.runtime.Context](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/Context.java);
import [com.amazonaws.services.lambda.runtime.LambdaLogger](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/LambdaLogger.java);
import [com.amazonaws.services.lambda.runtime.RequestHandler](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/RequestHandler.java);

import java.util.Map;

// Handler value: example.Handler
public class Handler implements RequestHandler<Map<String,String>, Void>{

  @Override
  public Void handleRequest(Map<String,String> event, Context context)
  {
    LambdaLogger logger = context.getLogger();
    logger.log("EVENT TYPE: " + event.getClass());
    return null;
  }
}
```

A função registra em log o tipo de classe do evento de entrada antes de retornar `null`.

**Example saída do log**  

```
EVENT TYPE: class java.util.LinkedHashMap
```

A interface para o objeto de contexto está disponível na biblioteca [aws-lambda-java-core](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-core). É possível implementar essa interface para criar uma classe de contexto para teste. O exemplo a seguir mostra uma classe de contexto que retorna valores fictícios para a maioria das propriedades e um logger de teste funcional.

**Example [src/test/java/example/TestContext.java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic/src/test/java/example/TestContext.java)**  

```
package example;

import [com.amazonaws.services.lambda.runtime.Context](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/Context.java);
import [com.amazonaws.services.lambda.runtime.CognitoIdentity](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/CognitoIdentity.java);
import [com.amazonaws.services.lambda.runtime.ClientContext](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/ClientContext.java);
import [com.amazonaws.services.lambda.runtime.LambdaLogger](https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/LambdaLogger.java);

public class TestContext implements Context{

  public TestContext() {}
  public String getAwsRequestId(){
    return new String("495b12a8-xmpl-4eca-8168-160484189f99");
  }
  public String getLogGroupName(){
    return new String("/aws/lambda/my-function");
  }
  public String getLogStreamName(){
    return new String("2020/02/26/[$LATEST]704f8dxmpla04097b9134246b8438f1a");
  }
  public String getFunctionName(){
    return new String("my-function");
  }
  public String getFunctionVersion(){
    return new String("$LATEST");
  }
  public String getInvokedFunctionArn(){
    return new String("arn:aws:lambda:us-east-2:123456789012:function:my-function");
  }
  public CognitoIdentity getIdentity(){
    return null;
  }
  public ClientContext getClientContext(){
    return null;
  }
  public int getRemainingTimeInMillis(){
    return 300000;
  }
  public int getMemoryLimitInMB(){
    return 512;
  }
  public LambdaLogger getLogger(){
    return new TestLogger();
  }

}
```

Para obter mais informações sobre registro em log, consulte [Registrar em log e monitorar funções do Lambda em Java](java-logging.md).

## Contexto em aplicativos de exemplo
<a name="java-context-samples"></a>

O repositório do GitHub para este guia inclui aplicativos de exemplo que demonstram o uso do objeto de contexto. Cada aplicativo de exemplo inclui scripts para fácil implantação e limpeza, um modelo do AWS Serverless Application Model (AWS SAM) e recursos de suporte.

**Aplicações de exemplo do Lambda em Java**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java): uma função Java que demonstra como você pode usar o Lambda para processar pedidos. Essa função ilustra como definir e desserializar um objeto de evento de entrada personalizado, usar o AWS SDK e gerar logs de saída.
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic): uma coleção de funções Java mínimas com testes de unidade e configuração de registro em log variável.
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events): uma coleção de funções do Java contendo código básico sobre como lidar com eventos de vários serviços, como o Amazon API Gateway, o Amazon SQS e o Amazon Kinesis. Essas funções usam a versão mais recente da biblioteca [aws-lambda-java-events](java-package.md) (3.0.0 e versões mais recentes). Estes exemplos não exigem o AWS SDK como dependência.
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java): uma função em Java que processa eventos de notificação do Amazon S3 e usa a Java Class Library (JCL) para criar miniaturas de arquivos de imagem enviados por upload.
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java): uma função Java que ilustra como usar uma camada do Lambda para empacotar dependências separadamente do código da função principal.

# Registrar em log e monitorar funções do Lambda em Java
<a name="java-logging"></a>

O AWS Lambda monitora automaticamente as funções do Lambda e envia entradas de logs para o Amazon CloudWatch. Sua função do Lambda vem com um grupo de logs do CloudWatch Logs e uma transmissão de logs para cada instância de sua função. O ambiente de runtime do Lambda envia detalhes sobre cada invocação e outras saídas do código da função para o fluxo de logs. Para obter mais informações sobre o CloudWatch Logs, consulte [Enviar logs de função do Lambda para o CloudWatch Logs](monitoring-cloudwatchlogs.md).

Para gerar os logs do código da sua função, use métodos no [java.lang.System](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html) ou qualquer módulo de registro em log que grave em stdout ou stderr.

**Topics**
+ [Criar uma função que retorna logs](#java-logging-output)
+ [Usar controles avançados de registro em log do Lambda com Java](#java-logging-advanced)
+ [Implementar registro em log avançado com Log4j2 e SLF4J](#java-logging-log4j2)
+ [Usar outras ferramentas e bibliotecas de registro em log](#java-tools-libraries)
+ [Uso do Powertools para AWS Lambda (Java) e do AWS SAM para registro em log estruturado](#java-logging-sam)
+ [Visualizar logs no console do Lambda](#java-logging-console)
+ [Visualização de logs no console do CloudWatch](#java-logging-cwconsole)
+ [Visualizar logs usando a AWS Command Line Interface (AWS CLI)](#java-logging-cli)
+ [Excluir logs](#java-logging-delete)
+ [Código de exemplo de registro em log](#java-logging-samples)

## Criar uma função que retorna logs
<a name="java-logging-output"></a>

Para gerar os logs do código da função, use métodos no [java.lang.System](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html) ou qualquer módulo de registro em log que grave no `stdout` ou no `stderr`. A biblioteca [aws-lambda-java-core](java-package.md) fornece uma classe do logger chamada `LambdaLogger` que você pode acessar a partir do objeto de contexto. A classe do logger oferece suporte a logs de várias linhas.

O exemplo a seguir usa o logger `LambdaLogger` fornecido pelo objeto de contexto.

**Example Handler.java**  

```
// Handler value: example.Handler
public class Handler implements RequestHandler<Object, String>{
  Gson gson = new GsonBuilder().setPrettyPrinting().create();
  @Override
  public String handleRequest(Object event, Context context)
  {
    LambdaLogger logger = context.getLogger();
    String response = new String("SUCCESS");
    // log execution details
    logger.log("ENVIRONMENT VARIABLES: " + gson.toJson(System.getenv()));
    logger.log("CONTEXT: " + gson.toJson(context));
    // process event
    logger.log("EVENT: " + gson.toJson(event));
    return response;
  }
}
```

**Example formato do log**  

```
START RequestId: 6bc28136-xmpl-4365-b021-0ce6b2e64ab0 Version: $LATEST
ENVIRONMENT VARIABLES: 
{
    "_HANDLER": "example.Handler",
    "AWS_EXECUTION_ENV": "AWS_Lambda_java8",
    "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "512",
    ...
}
CONTEXT: 
{
    "memoryLimit": 512,
    "awsRequestId": "6bc28136-xmpl-4365-b021-0ce6b2e64ab0",
    "functionName": "java-console",
    ...
}
EVENT:
{
  "records": [
    {
      "messageId": "19dd0b57-xmpl-4ac1-bd88-01bbb068cb78",
      "receiptHandle": "MessageReceiptHandle",
      "body": "Hello from SQS!",
       ...
    }
  ]
}
END RequestId: 6bc28136-xmpl-4365-b021-0ce6b2e64ab0
REPORT RequestId: 6bc28136-xmpl-4365-b021-0ce6b2e64ab0	Duration: 198.50 ms	Billed Duration: 724 ms	Memory Size: 512 MB	Max Memory Used: 90 MB	Init Duration: 524.75 ms
```

O runtime do Java registra em log as linhas `START`, `END` e `REPORT` para cada invocação. A linha do relatório fornece os seguintes detalhes:

**RELATAR campos de dados de linha**
+ **RequestId**: o ID de solicitação exclusivo para a invocação.
+ **Duração**: a quantidade de tempo que o método de manipulador da função gastou processando o evento.
+ **Duração faturada**: a quantia de tempo faturada para a invocação.
+ **Tamanho da memória**: a quantidade de memória alocada para a função.
+ **Memória máxima utilizada**: a quantidade de memória utilizada pela função. Quando as invocações compartilham um ambiente de execução, o Lambda relata a memória máxima usada em todas as invocações. Esse comportamento pode resultar em um valor relatado maior do que o esperado.
+ **Duração inicial**: para a primeira solicitação atendida, a quantidade de tempo que o runtime levou para carregar a função e executar o código fora do método do handler.
+ **XRAY TraceId**: para solicitações rastreadas, o [ID de rastreamento do AWS X-Ray](services-xray.md).
+ **SegmentId**: para solicitações rastreadas, o ID do segmento do X-Ray.
+ **Amostragem**: para solicitações rastreadas, o resultado da amostragem.

## Usar controles avançados de registro em log do Lambda com Java
<a name="java-logging-advanced"></a>

Para dar mais controle sobre como os logs das funções são capturados, processados e consumidos, você pode configurar as seguintes opções de log para runtimes compatíveis do Java:
+ **Formato do log**: selecione entre texto simples e formato JSON estruturado para os logs da sua função.
+ **Nível de log**: para logs no formato JSON, escolha o nível de detalhe dos logs enviados pelo Lambda para o CloudWatch, como ERROR, DEBUG ou INFO.
+ **Grupo de logs**: escolha o grupo de logs do CloudWatch para o qual sua função envia logs.

Para obter mais informações sobre essas opções de registro em log e instruções sobre como configurar a função para usá-las, consulte [Configurar controles avançados de registro em log para funções do Lambda](monitoring-logs.md#monitoring-cloudwatchlogs-advanced).

Para usar as opções de formato de log e nível de log com as funções do Lambda para Java, consulte as orientações nas seções a seguir.

### Usar logs em formato JSON estruturado com Java
<a name="java-logging-advanced-JSON"></a>

Se você selecionar JSON para o formato de log da função, o Lambda enviará a saída de logs usando a classe `LambdaLogger` como JSON estruturado. Cada objeto de log JSON contém pelo menos quatro pares de valores-chave com as seguintes chaves:
+ `"timestamp"`: o horário em que a mensagem de log foi gerada.
+ `"level"`: o nível de log atribuído à mensagem.
+ `"message"`: o conteúdo da mensagem de log.
+ `"AWSrequestId"`: o ID de solicitação exclusivo para invocar a função.

Dependendo do método de registro em log usado, as saídas de log da função capturadas no formato JSON também podem conter pares de valores de chave adicionais.

Para atribuir um nível aos logs que você criar usando o logger `LambdaLogger`, você precisa fornecer um argumento `LogLevel` no comando de registro em log, conforme mostrado no exemplo a seguir.

**Example Código de registro em log do Java**  

```
LambdaLogger logger = context.getLogger();
logger.log("This is a debug log", LogLevel.DEBUG);
```

A saída de log desse exemplo de código seria capturada no CloudWatch Logs da seguinte forma:

**Example Registro em log JSON**  

```
{
    "timestamp":"2023-11-01T00:21:51.358Z",
    "level":"DEBUG",
    "message":"This is a debug log",
    "AWSrequestId":"93f25699-2cbf-4976-8f94-336a0aa98c6f"
}
```

Se você não atribuir um nível à saída de log, o Lambda atribuirá automaticamente o nível INFO a ele.

Se o código já usa outra biblioteca de logs para produzir logs JSON estruturados, você não precisa fazer nenhuma alteração. O Lambda não codifica duas vezes nenhum log que já esteja codificado em JSON. Mesmo que a função seja configurada para usar logs em formato JSON, suas saídas de log serão exibidas no CloudWatch com a estrutura JSON que você definiu.

### Usar a filtragem em nível de log com Java
<a name="java-logging-advanced-levels"></a>

Para o AWS Lambda filtrar os logs de aplicação de acordo com o nível de log, a função precisa usar logs em formato JSON. Isso pode ser feito de duas maneiras:
+ Crie saídas de log usando o padrão `LambdaLogger` e configure a função para usar logs em formato JSON. Assim, o Lambda filtrará as saídas de log usando o par de valores-chave “nível” no objeto JSON descrito em [Usar logs em formato JSON estruturado com Java](#java-logging-advanced-JSON). Para saber como configurar o formato de log da função, consulte [Configurar controles avançados de registro em log para funções do Lambda](monitoring-logs.md#monitoring-cloudwatchlogs-advanced).
+ Use outro método ou biblioteca de logs para criar logs JSON estruturados no código, de modo que incluam um par de valores-chave de “nível” para definir o nível da saída de log. Também é possível usar qualquer biblioteca de logs que permita a gravação em logs JSON em `stdout` ou `stderr`. Por exemplo, é possível usar o Powertools para AWS Lambda ou o pacote Log4j2 para gerar saídas de log JSON estruturado do seu código. Consulte [Uso do Powertools para AWS Lambda (Java) e do AWS SAM para registro em log estruturado](#java-logging-sam) e [Implementar registro em log avançado com Log4j2 e SLF4J](#java-logging-log4j2) para saber mais.

Ao configurar sua função para usar a filtragem em nível de log, você precisa selecionar entre as seguintes opções para o nível do logs enviados pelo Lambda para o CloudWatch Logs:


| Nível de log | Uso padrão | 
| --- | --- | 
| TRACE (mais detalhes) | As informações mais detalhadas usadas para rastrear o caminho da execução do código | 
| DEBUG | Informações detalhadas para depuração do sistema | 
| INFORMAÇÕES | Mensagens que registram a operação normal da função | 
| WARN | Mensagens sobre possíveis erros que podem levar a um comportamento inesperado se não forem corrigidos | 
| ERRO | Mensagens sobre problemas que impedem que o código funcione conforme o esperado | 
| FATAL (menos detalhes) | Mensagens sobre erros graves que fazem a aplicação parar de funcionar | 

Para que o Lambda filtre os logs da função, você também precisa incluir um par de valores-chave `"timestamp"` na saída do log JSON. A hora deve ser especificada em um formato [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) válido de carimbo de data/hora. Se você não fornecer um carimbo de data/hora válido, o Lambda atribuirá ao log o nível INFO e adicionará um carimbo de data/hora.

O Lambda envia logs do nível selecionado, e dos níveis inferiores, para o CloudWatch. Por exemplo, se você configurar um nível de log de WARN, o Lambda enviará logs correspondentes aos níveis WARN, ERROR e FATAL.

## Implementar registro em log avançado com Log4j2 e SLF4J
<a name="java-logging-log4j2"></a>

**nota**  
 O AWS Lambda não inclui o Log4j2 em seus runtimes gerenciados ou imagens de contêiner base. Portanto, estes não são afetados pelos problemas descritos em CVE-2021-44228, CVE-2021-45046 e CVE-2021-45105.   
 Para casos em que uma função do cliente contém uma versão do Log4j2 impactada, aplicamos uma alteração aos [runtimes gerenciados](lambda-runtimes.md) e [imagens do contêiner base](java-image.md) do Lambda Java que ajuda a mitigar os problemas em CVE-2021-44228, CVE-2021-45046 e CVE-2021-45105. Como resultado dessa alteração, os clientes que usam o Log4J2 podem ver mais uma entrada de log, semelhante a “”. "`Transforming org/apache/logging/log4j/core/lookup/JndiLookup (java.net.URLClassLoader@...)`". Todas as strings de log que referenciem o mapeador jndi na saída Log4J2 serão substituídas por “”. "`Patched JndiLookup::lookup()`".   
 Independentemente dessa mudança, é altamente recomendável que todos os clientes cujas funções incluam o Log4j2 atualizem para a versão mais recente. Especificamente, os clientes que usam a biblioteca aws-lambda-java-log4j2 em suas funções devem atualizar para a versão 1.5.0 (ou posterior) e reimplantar suas funções. Essa versão atualiza as dependências do utilitário Log4j2 subjacentes para a versão 2.17.0 (ou posterior). O binário aws-lambda-java-log4j2 atualizado está disponível no [repositório do Maven](https://repo1.maven.org/maven2/com/amazonaws/aws-lambda-java-log4j2/), e seu código-fonte está disponível no [Github](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-log4j2).   
 Por fim, observe que qualquer biblioteca relacionada ao **aws-lambda-java-log4j (v1.0.0 or 1.0.1)** **não** deve ser usada em **nenhuma** circunstância. Essas bibliotecas estão relacionadas à versão 1.x do log4j, que foi encerrada em 2015. Não há suporte, manutenção nem patches para essas bibliotecas, e elas apresentam vulnerabilidades de segurança conhecidas. 

Para personalizar a saída de log, oferecer suporte ao registro em log durante testes de unidade e registrar chamadas do AWS SDK em log, use o Apache Log4j2 com o SLF4J. O Log4j é uma biblioteca de registro em log para programas Java que permite configurar níveis de log e usar bibliotecas de appender. O SLF4J é uma biblioteca de fachada que permite alterar qual biblioteca você usa sem alterar o código da função.

Para adicionar o ID de solicitação aos logs da sua função, use o appender na biblioteca [aws-lambda-java-log4j2](java-package.md).

**Example [src/main/resources/log4j2.xml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java/src/main/resources/log4j2.xml): configuração do appender**  

```
<Configuration>
  <Appenders>
    <Lambda name="Lambda" format="${env:AWS_LAMBDA_LOG_FORMAT:-TEXT}">
       <LambdaTextFormat>
         <PatternLayout>
             <pattern>%d{yyyy-MM-dd HH:mm:ss} %X{AWSRequestId} %-5p %c{1} - %m%n </pattern>
         </PatternLayout>
       </LambdaTextFormat>
       <LambdaJSONFormat>
         <JsonTemplateLayout eventTemplateUri="classpath:LambdaLayout.json" />
       </LambdaJSONFormat>
     </Lambda>
   </Appenders>
   <Loggers>
     <Root level="${env:AWS_LAMBDA_LOG_LEVEL:-INFO}">
       <AppenderRef ref="Lambda"/>
     </Root>
     <Logger name="software.amazon.awssdk" level="WARN" />
     <Logger name="software.amazon.awssdk.request" level="DEBUG" />
   </Loggers>
 </Configuration>
```

É possível decidir como os logs do Log4j2 são configurados para saídas em texto simples ou JSON especificando um layout nas tags `<LambdaTextFormat>` e `<LambdaJSONFormat>`.

Neste exemplo, no modo de texto, cada linha é precedida com a data, a hora, o ID da solicitação, o nível do log e o nome da classe. No modo JSON, `<JsonTemplateLayout>` é usado com uma configuração que está incluída na biblioteca `aws-lambda-java-log4j2`.

O SLF4J é uma biblioteca de fachada para registro em log em código Java. No código da função, use o logger factory SLF4J para recuperar um logger com métodos para níveis de log como `info()` e `warn()`. Na configuração da compilação, inclua a biblioteca de registro em log e o adaptador SLF4J no classpath. Alterando as bibliotecas na configuração de compilação, é possível alterar o tipo de logger sem alterar o código da função. O SLF4J é necessário para capturar logs do SDK for Java.

No exemplo de código a seguir, a classe de manipulador usa SLF4J para recuperar um logger.

**Example [src/main/java/example/HandlerS3.java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events/src/main/java/example/HandlerS3.java): registro em log com o SLF4J**  

```
package example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.S3Event;

import static org.apache.logging.log4j.CloseableThreadContext.put;


public class HandlerS3 implements RequestHandler<S3Event, String>{
    private static final Logger logger = LoggerFactory.getLogger(HandlerS3.class);

    @Override
    public String handleRequest(S3Event event, Context context) {
        for(var record : event.getRecords()) {
            try (var loggingCtx = put("awsRegion", record.getAwsRegion())) {
                loggingCtx.put("eventName", record.getEventName());
                loggingCtx.put("bucket", record.getS3().getBucket().getName());
                loggingCtx.put("key", record.getS3().getObject().getKey());

                logger.info("Handling s3 event");
            }
        }

        return "Ok";
    }
}
```

Esse código gera uma saída de log semelhante à seguinte:

**Example formato do log**  

```
{
    "timestamp": "2023-11-15T16:56:00.815Z",
    "level": "INFO",
    "message": "Handling s3 event",
    "logger": "example.HandlerS3",
    "AWSRequestId": "0bced576-3936-4e5a-9dcd-db9477b77f97",
    "awsRegion": "eu-south-1",
    "bucket": "java-logging-test-input-bucket",
    "eventName": "ObjectCreated:Put",
    "key": "test-folder/"
}
```

A configuração de compilação usa dependências de runtime no appender e no adaptador SLF4J do Lambda, além de dependências de implementação no Log4J2.

**Example build.gradle: dependências de registro em log**  

```
dependencies {
    ...
    'com.amazonaws:aws-lambda-java-log4j2:[1.6.0,)',
    'com.amazonaws:aws-lambda-java-events:[3.11.3,)',
    'org.apache.logging.log4j:log4j-layout-template-json:[2.17.1,)',
    'org.apache.logging.log4j:log4j-slf4j2-impl:[2.19.0,)',
    ...
}
```

Quando você executa seu código localmente para testes, o objeto de contexto com o logger do Lambda não está disponível e não há nenhum ID de solicitação para o appender do Lambda usar. Para obter exemplos de configurações de teste, consulte as aplicações de exemplo na próxima seção. 

## Usar outras ferramentas e bibliotecas de registro em log
<a name="java-tools-libraries"></a>

O [Powertools para AWS Lambda (Java)](https://docs.aws.amazon.com/powertools/java/) é um kit de ferramentas para desenvolvedores para implementar as práticas recomendadas da tecnologia sem servidor e aumentar a velocidade do desenvolvedor. O [utilitário de logs](https://docs.aws.amazon.com/powertools/java/latest/core/logging/) fornece um registrador de logs otimizado para Lambda que inclui informações adicionais sobre o contexto da função em todas as suas funções, com saída estruturada como JSON. Use esse utilitário para fazer o seguinte:
+ Capturar campos-chave do contexto do Lambda, inicialização a frio e estruturas registrando em log a saída como JSON
+ Registrar em log eventos de invocação do Lambda quando instruído (desativado por padrão)
+ Imprimir todos os logs somente para uma porcentagem das invocações por meio da amostragem de logs (desativado por padrão)
+ Anexar chaves adicionais ao log estruturado a qualquer momento
+ Use um formatador de log personalizado (Bring Your Own Formatter) para gerar logs em uma estrutura compatível com o RFC de logs da sua organização

## Uso do Powertools para AWS Lambda (Java) e do AWS SAM para registro em log estruturado
<a name="java-logging-sam"></a>

Siga as etapas abaixo para baixar, criar e implantar um exemplo da aplicação Hello World em Java com os módulos integrados do [Powertools para AWS Lambda (Java)](https://docs.aws.amazon.com/powertools/java/latest/) usando o AWS SAM. Esta aplicação implementa um backend de API básico e usa o Powertools para emitir logs, métricas e rastreamentos. Consiste em um endpoint do Amazon API Gateway e uma função do Lambda. Quando você envia uma solicitação GET ao endpoint do API Gateway, a função do Lambda invoca, envia logs e métricas usando o formato de métricas incorporadas ao CloudWatch e envia rastreamentos ao AWS X-Ray. A função retorna uma mensagem `hello world`.

**Pré-requisitos**

Para executar as etapas desta seção, você deve ter o seguinte:
+ Java 11
+ [AWS CLI versão 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI versão 1.75 ou posterior](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Se você tiver uma versão mais antiga da CLI do AWS SAM, consulte [Atualizando a CLI do AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Implantar uma aplicação de exemplo do AWS SAM**

1. Inicialize a aplicação usando o modelo Java do Hello World.

   ```
   sam init --app-template hello-world-powertools-java --name sam-app --package-type Zip --runtime java11 --no-tracing
   ```

1. Crie a aplicação.

   ```
   cd sam-app && sam build
   ```

1. Implante o aplicativo.

   ```
   sam deploy --guided
   ```

1. Siga as instruções na tela. Para aceitar as opções padrão fornecidas na experiência interativa, pressione `Enter`.
**nota**  
Em **HelloWorldFunction pode não ter autorização definida, tudo bem?**, certifique-se de inserir `y`.

1. Obtenha o URL da aplicação implantada:

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. Invoque o endpoint da API:

   ```
   curl -X GET <URL_FROM_PREVIOUS_STEP>
   ```

   Se tiver êxito, você verá esta resposta:

   ```
   {"message":"hello world"}
   ```

1. Para obter os logs da função, execute [sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html). Para obter mais informações, consulte [Trabalhar com logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html) no *Guia do desenvolvedor do AWS Serverless Application Model*.

   ```
   sam logs --stack-name sam-app
   ```

   O resultado de saída do log se parece com:

   ```
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:34.095000 INIT_START Runtime Version: java:11.v15    Runtime Version ARN: arn:aws:lambda:eu-central-1::runtime:0a25e3e7a1cc9ce404bc435eeb2ad358d8fa64338e618d0c224fe509403583ca
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:34.114000 Picked up JAVA_TOOL_OPTIONS: -XX:+TieredCompilation -XX:TieredStopAtLevel=1
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:34.793000 Transforming org/apache/logging/log4j/core/lookup/JndiLookup (lambdainternal.CustomerClassLoader@1a6c5a9e)
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:35.252000 START RequestId: 7fcf1548-d2d4-41cd-a9a8-6ae47c51f765 Version: $LATEST
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:36.531000 {
     "_aws": {
       "Timestamp": 1675416276051,
       "CloudWatchMetrics": [
         {
           "Namespace": "sam-app-powerools-java",
           "Metrics": [
             {
               "Name": "ColdStart",
               "Unit": "Count"
             }
           ],
           "Dimensions": [
             [
               "Service",
               "FunctionName"
             ]
           ]
         }
       ]
     },
     "function_request_id": "7fcf1548-d2d4-41cd-a9a8-6ae47c51f765",
     "traceId": "Root=1-63dcd2d1-25f90b9d1c753a783547f4dd;Parent=e29684c1be352ce4;Sampled=1",
     "FunctionName": "sam-app-HelloWorldFunction-y9Iu1FLJJBGD",
     "functionVersion": "$LATEST",
     "ColdStart": 1.0,
     "Service": "service_undefined",
     "logStreamId": "2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81",
     "executionEnvironment": "AWS_Lambda_java11"
   }
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:36.974000 Feb 03, 2023 9:24:36 AM com.amazonaws.xray.AWSXRayRecorder <init>
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:36.993000 Feb 03, 2023 9:24:36 AM com.amazonaws.xray.config.DaemonConfiguration <init>
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:36.993000 INFO: Environment variable AWS_XRAY_DAEMON_ADDRESS is set. Emitting to daemon on address XXXX.XXXX.XXXX.XXXX:2000.
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:37.331000 09:24:37.294 [main] INFO  helloworld.App - {"version":null,"resource":"/hello","path":"/hello/","httpMethod":"GET","headers":{"Accept":"*/*","CloudFront-Forwarded-Proto":"https","CloudFront-Is-Desktop-Viewer":"true","CloudFront-Is-Mobile-Viewer":"false","CloudFront-Is-SmartTV-Viewer":"false","CloudFront-Is-Tablet-Viewer":"false","CloudFront-Viewer-ASN":"16509","CloudFront-Viewer-Country":"IE","Host":"XXXX.execute-api.eu-central-1.amazonaws.com","User-Agent":"curl/7.86.0","Via":"2.0 f0300a9921a99446a44423d996042050.cloudfront.net (CloudFront)","X-Amz-Cf-Id":"t9W5ByT11HaY33NM8YioKECn_4eMpNsOMPfEVRczD7T1RdhbtiwV1Q==","X-Amzn-Trace-Id":"Root=1-63dcd2d1-25f90b9d1c753a783547f4dd","X-Forwarded-For":"XX.XXX.XXX.XX, XX.XXX.XXX.XX","X-Forwarded-Port":"443","X-Forwarded-Proto":"https"},"multiValueHeaders":{"Accept":["*/*"],"CloudFront-Forwarded-Proto":["https"],"CloudFront-Is-Desktop-Viewer":["true"],"CloudFront-Is-Mobile-Viewer":["false"],"CloudFront-Is-SmartTV-Viewer":["false"],"CloudFront-Is-Tablet-Viewer":["false"],"CloudFront-Viewer-ASN":["16509"],"CloudFront-Viewer-Country":["IE"],"Host":["XXXX.execute-api.eu-central-1.amazonaws.com"],"User-Agent":["curl/7.86.0"],"Via":["2.0 f0300a9921a99446a44423d996042050.cloudfront.net (CloudFront)"],"X-Amz-Cf-Id":["t9W5ByT11HaY33NM8YioKECn_4eMpNsOMPfEVRczD7T1RdhbtiwV1Q=="],"X-Amzn-Trace-Id":["Root=1-63dcd2d1-25f90b9d1c753a783547f4dd"],"X-Forwarded-For":["XXX, XXX"],"X-Forwarded-Port":["443"],"X-Forwarded-Proto":["https"]},"queryStringParameters":null,"multiValueQueryStringParameters":null,"pathParameters":null,"stageVariables":null,"requestContext":{"accountId":"XXX","stage":"Prod","resourceId":"at73a1","requestId":"ba09ecd2-acf3-40f6-89af-fad32df67597","operationName":null,"identity":{"cognitoIdentityPoolId":null,"accountId":null,"cognitoIdentityId":null,"caller":null,"apiKey":null,"principalOrgId":null,"sourceIp":"54.240.197.236","cognitoAuthenticationType":null,"cognitoAuthenticationProvider":null,"userArn":null,"userAgent":"curl/7.86.0","user":null,"accessKey":null},"resourcePath":"/hello","httpMethod":"GET","apiId":"XXX","path":"/Prod/hello/","authorizer":null},"body":null,"isBase64Encoded":false}
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:37.351000 09:24:37.351 [main] INFO  helloworld.App - Retrieving https://checkip.amazonaws.com
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:39.313000 {
     "function_request_id": "7fcf1548-d2d4-41cd-a9a8-6ae47c51f765",
     "traceId": "Root=1-63dcd2d1-25f90b9d1c753a783547f4dd;Parent=e29684c1be352ce4;Sampled=1",
     "xray_trace_id": "1-63dcd2d1-25f90b9d1c753a783547f4dd",
     "functionVersion": "$LATEST",
     "Service": "service_undefined",
     "logStreamId": "2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81",
     "executionEnvironment": "AWS_Lambda_java11"
   }
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:39.371000 END RequestId: 7fcf1548-d2d4-41cd-a9a8-6ae47c51f765
   2025/09/03/[$LATEST]851411a899b545eea2cffeba4cfbec81 2023-02-03T09:24:39.371000 REPORT RequestId: 7fcf1548-d2d4-41cd-a9a8-6ae47c51f765    Duration: 4118.98 ms    Billed Duration: 5275 ms    Memory Size: 512 MB    Max Memory Used: 152 MB    Init Duration: 1155.47 ms    
   XRAY TraceId: 1-63dcd2d1-25f90b9d1c753a783547f4dd    SegmentId: 3a028fee19b895cb    Sampled: true
   ```

1. Este é um endpoint de API pública que é acessado pela Internet. Recomendamos excluir o endpoint após o teste.

   ```
   sam delete
   ```

### Gerenciar a retenção de logs
<a name="java-log-retention"></a>

Os grupos de logs não são excluídos automaticamente excluídos quando você exclui uma função. Para evitar armazenar logs por tempo indeterminado, exclua o grupo de logs ou configure um período de retenção após o qual o CloudWatch excluirá os logs automaticamente. Para configurar a retenção de logs, adicione o seguinte ao seu modelo do AWS SAM:

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      # Omitting other properties

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${HelloWorldFunction}"
      RetentionInDays: 7
```

## Visualizar logs no console do Lambda
<a name="java-logging-console"></a>

É possível usar o console do Lambda para exibir a saída do log depois de invocar uma função do Lambda.

Se seu código puder ser testado no editor de **Código** incorporado, você encontrará logs nos **resultados de execução**. Ao usar o recurso de teste do console para invocar uma função, você encontrará **Saída de log** na seção **Detalhes**.

## Visualização de logs no console do CloudWatch
<a name="java-logging-cwconsole"></a>

É possível usar o console do Amazon CloudWatch para exibir logs de todas as invocações da função do Lambda.

**Para visualizar logs no console do CloudWatch**

1. No console do Amazon CloudWatch, abra a [página Log groups](https://console.aws.amazon.com/cloudwatch/home?#logs:) (Grupos de log).

1. Escolha o grupo de logs de sua função (**/aws/lambda/*nome-de-sua-função***).

1. Escolha um stream de logs.

Cada fluxo de log corresponde a uma [instância da sua função](lambda-runtime-environment.md). Um fluxo de logs é exibido quando você atualiza sua função do Lambda e quando mais instâncias são criadas para lidar com invocações simultâneas. Para localizar logs de uma invocação específica, recomendamos intrumentar sua função com AWS X-Ray. O X-Ray registra detalhes sobre a solicitação e o stream de logs no rastreamento.

## Visualizar logs usando a AWS Command Line Interface (AWS CLI)
<a name="java-logging-cli"></a>

O AWS CLI é uma ferramenta de código aberto que permite interagir com os serviços do AWS usando comandos no shell da linha de comando. Para concluir as etapas desta seção, você deve ter a [versão 2 da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

É possível usar a [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) para recuperar logs de uma invocação usando a opção de comando `--log-type`. A resposta contém um campo `LogResult` com até 4 KB de logs codificados em base64 obtidos da invocação.

**Example recuperar um ID de log**  
O exemplo a seguir mostra como recuperar um *ID de log* do campo `LogResult` para uma função chamada `my-function`.  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
A seguinte saída deverá ser mostrada:  

```
{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
```

**Example decodificar os logs**  
No mesmo prompt de comando, use o utilitário `base64` para decodificar os logs. O exemplo a seguir mostra como recuperar logs codificados em base64 de `my-function`.  

```
aws lambda invoke --function-name my-function out --log-type Tail \
--query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
```
A opção **cli-binary-format** será necessária se você estiver usando a AWS CLI versão 2. Para que essa seja a configuração padrão, execute `aws configure set cli-binary-format raw-in-base64-out`. Para obter mais informações, consulte [A AWS CLI comporta opções de linha de comando globais](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) no *Guia do usuário da AWS Command Line Interface versão 2*.  
A seguinte saída deverá ser mostrada:  

```
START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB
```
O utilitário `base64` está disponível no Linux, macOS e [Ubuntu no Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10). Os usuários do macOS precisam usar `base64 -D`.

**Example get-logs.sh script**  
No mesmo prompt de comando, use o script a seguir para fazer download dos últimos cinco eventos de log. O script usa `sed` para remover as aspas do arquivo de saída e fica inativo por 15 segundos para que os logs tenham tempo de ficar disponíveis. A saída inclui a resposta do Lambda, e a saída do comando `get-log-events`.   
Copie o conteúdo do exemplo de código a seguir e salve no diretório de seu projeto do Lambda como `get-logs.sh`.  
A opção **cli-binary-format** será necessária se você estiver usando a AWS CLI versão 2. Para que essa seja a configuração padrão, execute `aws configure set cli-binary-format raw-in-base64-out`. Para obter mais informações, consulte [A AWS CLI comporta opções de linha de comando globais](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) no *Guia do usuário da AWS Command Line Interface versão 2*.  

```
#!/bin/bash
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out
sed -i'' -e 's/"//g' out
sleep 15
aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name stream1 --limit 5
```

**Example macOS e Linux (somente)**  
No mesmo prompt de comando, os usuários do macOS e do Linux podem precisar executar o comando a seguir para garantir que o script seja executável.  

```
chmod -R 755 get-logs.sh
```

**Example recuperar os últimos cinco eventos de log**  
No mesmo prompt de comando, execute o script a seguir para obter os últimos cinco eventos de log.  

```
./get-logs.sh
```
A seguinte saída deverá ser mostrada:  

```
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
{
    "events": [
        {
            "timestamp": 1559763003171,
            "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n",
            "ingestionTime": 1559763003309
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r  \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r  \"key\": \"value\"\r}\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n",
            "ingestionTime": 1559763018353
        }
    ],
    "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795",
    "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080"
}
```

## Excluir logs
<a name="java-logging-delete"></a>

Os grupos de logs não são excluídos automaticamente excluídos quando você exclui uma função. Para evitar armazenar logs indefinidamente, exclua o grupo de logs ou[configurar um período de retenção](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention)após o qual os logs são excluídos automaticamente.

## Código de exemplo de registro em log
<a name="java-logging-samples"></a>

O repositório do GitHub para este guia inclui aplicativos de exemplo que demonstram o uso de várias configurações de registro em log. Cada aplicativo de exemplo inclui scripts para fácil implantação e limpeza, um modelo do AWS SAM e recursos de suporte.

**Aplicações de exemplo do Lambda em Java**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java): uma função Java que demonstra como você pode usar o Lambda para processar pedidos. Essa função ilustra como definir e desserializar um objeto de evento de entrada personalizado, usar o AWS SDK e gerar logs de saída.
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic): uma coleção de funções Java mínimas com testes de unidade e configuração de registro em log variável.
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events): uma coleção de funções do Java contendo código básico sobre como lidar com eventos de vários serviços, como o Amazon API Gateway, o Amazon SQS e o Amazon Kinesis. Essas funções usam a versão mais recente da biblioteca [aws-lambda-java-events](java-package.md) (3.0.0 e versões mais recentes). Estes exemplos não exigem o AWS SDK como dependência.
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java): uma função em Java que processa eventos de notificação do Amazon S3 e usa a Java Class Library (JCL) para criar miniaturas de arquivos de imagem enviados por upload.
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java): uma função Java que ilustra como usar uma camada do Lambda para empacotar dependências separadamente do código da função principal.

O aplicativo de exemplo `java-basic` mostra uma configuração mínima de registro em log que oferece suporte a testes de registro em log. O código do manipulador usa o logger `LambdaLogger` fornecido pelo objeto de contexto. Para testes, a aplicação usa uma classe `TestLogger` personalizada que implementa a interface `LambdaLogger` com um logger Log4j2. Ele usa o SLF4J como fachada para compatibilidade com o AWS SDK. As bibliotecas de registro em log são excluídas da saída de compilação para manter o pacote de implantação pequeno.

# Instrumentação do código Java no AWS Lambda
<a name="java-tracing"></a>

O Lambda se integra ao AWS X-Ray para ajudar você a rastrear, depurar e otimizar aplicações do Lambda. É possível usar o X-Ray para rastrear uma solicitação enquanto ela atravessa recursos na aplicação, o que pode incluir funções Lambda e outros produtos da AWS.

Para enviar dados de rastreamento ao X-Ray, você pode usar uma das duas bibliotecas SDK:
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel): uma distribuição segura, pronta para produção e com suporte na AWS do SDK OpenTelemetry (OTel).
+ [SDK do AWS X-Ray for Java](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java.html) – um SDK para geração e envio de dados de rastreamento ao X-Ray.
+ [Powertools para AWS Lambda (Java)](https://docs.aws.amazon.com/powertools/java/latest/): kit de ferramentas para desenvolvedores para implementar as práticas recomendadas da tecnologia sem servidor e aumentar a velocidade do desenvolvedor.

Cada um dos SDKs oferece maneiras de enviar dados de telemetria ao serviço do X-Ray. Em seguida, é possível usar o X-Ray para visualizar, filtrar e obter insights sobre as métricas de performance da aplicação para identificar problemas e oportunidades de otimização.

**Importante**  
Os SDKs do X-Ray e do Powertools para AWS Lambda fazem parte de uma solução de instrumentação totalmente integrada oferecida pela AWS. As camadas do Lambda para ADOT fazem parte de um padrão em todo o setor para instrumentação de rastreamento que coleta mais dados em geral, mas pode não ser adequado para todos os casos de uso. É possível implementar o rastreamento de ponta a ponta no X-Ray usando ambas as soluções. Para saber mais sobre como escolher entre elas, consulte [Como escolher entre os SDKs do AWS Distro para OpenTelemetry e do X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing).

**Topics**
+ [Uso do Powertools para AWS Lambda (Java) e do AWS SAM para rastreamento](#java-tracing-sam)
+ [Uso do Powertools para AWS Lambda (Java) e do AWS CDK para rastreamento](#java-tracing-cdk)
+ [Usar o ADOT para instrumentar funções do Java](#java-adot)
+ [Usar o SDK do X-Ray para instrumentar suas funções Java](#java-xray-sdk)
+ [Ativar o rastreamento com o console do Lambda](#java-tracing-console)
+ [Ativar o rastreamento com a API do Lambda](#java-tracing-api)
+ [Ativar o rastreamento com o CloudFormation](#java-tracing-cloudformation)
+ [Interpretar um rastreamento do X-Ray](#java-tracing-interpretation)
+ [Armazenar dependências de runtime em uma camada (SDK do X-Ray)](#java-tracing-layers)
+ [Rastreamento do X-Ray em aplicações de exemplo (SDK do X-Ray)](#java-tracing-samples)

## Uso do Powertools para AWS Lambda (Java) e do AWS SAM para rastreamento
<a name="java-tracing-sam"></a>

Siga as etapas abaixo para baixar, criar e implantar um exemplo da aplicação Hello World em Java com os módulos integrados do [Powertools para AWS Lambda (Java)](https://docs.powertools.aws.dev/lambda-java) usando o AWS SAM. Esta aplicação implementa um backend de API básico e usa o Powertools para emitir logs, métricas e rastreamentos. Consiste em um endpoint do Amazon API Gateway e uma função do Lambda. Quando você envia uma solicitação GET ao endpoint do API Gateway, a função do Lambda invoca, envia logs e métricas usando o formato de métricas incorporadas ao CloudWatch e envia rastreamentos ao AWS X-Ray. A função retorna uma mensagem `hello world`.

**Pré-requisitos**

Para executar as etapas desta seção, você deve ter o seguinte:
+ Java 11 ou posterior
+ [AWS CLI versão 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI versão 1.75 ou posterior](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Se você tiver uma versão mais antiga da CLI do AWS SAM, consulte [Atualizando a CLI do AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Implantar uma aplicação de exemplo do AWS SAM**

1. Inicialize a aplicação usando o modelo Java do Hello World.

   ```
   sam init --app-template hello-world-powertools-java --name sam-app --package-type Zip --runtime java11 --no-tracing
   ```

1. Crie a aplicação.

   ```
   cd sam-app && sam build
   ```

1. Implante o aplicativo.

   ```
   sam deploy --guided
   ```

1. Siga as instruções na tela. Para aceitar as opções padrão fornecidas na experiência interativa, pressione `Enter`.
**nota**  
Em **HelloWorldFunction pode não ter autorização definida, tudo bem?**, certifique-se de inserir `y`.

1. Obtenha o URL da aplicação implantada:

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. Invoque o endpoint da API:

   ```
   curl -X GET <URL_FROM_PREVIOUS_STEP>
   ```

   Se tiver êxito, você verá esta resposta:

   ```
   {"message":"hello world"}
   ```

1. Para obter os rastreamentos da função, execute [sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html).

   ```
   sam traces
   ```

   A saída de rastreamento se parece com:

   ```
   New XRay Service Graph
     Start time: 2025-02-03 14:31:48+01:00
     End time: 2025-02-03 14:31:48+01:00
     Reference Id: 0 - (Root) AWS::Lambda - sam-app-HelloWorldFunction-y9Iu1FLJJBGD - Edges: []
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 5.587
     Reference Id: 1 - client - sam-app-HelloWorldFunction-y9Iu1FLJJBGD - Edges: [0]
      Summary_statistics:
        - total requests: 0
        - ok count(2XX): 0
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0
   
   XRay Event [revision 3] at (2025-02-03T14:31:48.500000) with id (1-63dd0cc4-3c869dec72a586875da39777) and duration (5.603s)
    - 5.587s - sam-app-HelloWorldFunction-y9Iu1FLJJBGD [HTTP: 200]
    - 4.053s - sam-app-HelloWorldFunction-y9Iu1FLJJBGD
      - 1.181s - Initialization
      - 4.037s - Invocation
        - 1.981s - ## handleRequest
          - 1.840s - ## getPageContents
      - 0.000s - Overhead
   ```

1. Este é um endpoint de API pública que é acessado pela Internet. Recomendamos excluir o endpoint após o teste.

   ```
   sam delete
   ```

## Uso do Powertools para AWS Lambda (Java) e do AWS CDK para rastreamento
<a name="java-tracing-cdk"></a>

Siga as etapas abaixo para baixar, criar e implantar um exemplo da aplicação Hello World em Java com os módulos integrados do [Powertools para AWS Lambda (Java)](https://docs.powertools.aws.dev/lambda-java) usando o AWS CDK. Esta aplicação implementa um backend de API básico e usa o Powertools para emitir logs, métricas e rastreamentos. Consiste em um endpoint do Amazon API Gateway e uma função do Lambda. Quando você envia uma solicitação GET ao endpoint do API Gateway, a função do Lambda invoca, envia logs e métricas usando o formato de métricas incorporadas ao CloudWatch e envia rastreamentos ao AWS X-Ray. A função retorna uma mensagem de hello world.

**Pré-requisitos**

Para executar as etapas desta seção, você deve ter o seguinte:
+ Java 11 ou posterior
+ [AWS CLI versão 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS CDK versão 2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_prerequisites)
+ [AWS SAM CLI versão 1.75 ou posterior](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Se você tiver uma versão mais antiga da CLI do AWS SAM, consulte [Atualizando a CLI do AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Implantar uma aplicação de exemplo do AWS CDK**

1. Crie um diretório de projeto para sua aplicação.

   ```
   mkdir hello-world
   cd hello-world
   ```

1. Inicialize a aplicação.

   ```
   cdk init app --language java
   ```

1. Crie o projeto maven com o seguinte comando:

   ```
   mkdir app
   cd app
   mvn archetype:generate -DgroupId=helloworld -DartifactId=Function -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
   ```

1. Abra `pom.xml` no diretório `hello-world\app\Function` e substitua o código existente pelo código a seguir, que inclui dependências e plugins do maven para Powertools.

   ```
   <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>helloworld</groupId>
     <artifactId>Function</artifactId>
     <packaging>jar</packaging>
     <version>1.0-SNAPSHOT</version>
     <name>Function</name>
     <url>http://maven.apache.org</url>
   <properties>
       <maven.compiler.source>11</maven.compiler.source>
       <maven.compiler.target>11</maven.compiler.target>
       <log4j.version>2.17.2</log4j.version>
   </properties>
       <dependencies>
           <dependency>
               <groupId>junit</groupId>
               <artifactId>junit</artifactId>
               <version>3.8.1</version>
               <scope>test</scope>
           </dependency>
           <dependency>
               <groupId>software.amazon.lambda</groupId>
               <artifactId>powertools-tracing</artifactId>
               <version>1.3.0</version>
           </dependency>
           <dependency>
               <groupId>software.amazon.lambda</groupId>
               <artifactId>powertools-metrics</artifactId>
               <version>1.3.0</version>
           </dependency>
           <dependency>
               <groupId>software.amazon.lambda</groupId>
               <artifactId>powertools-logging</artifactId>
               <version>1.3.0</version>
           </dependency>
           <dependency>
               <groupId>com.amazonaws</groupId>
               <artifactId>aws-lambda-java-core</artifactId>
               <version>1.2.2</version>
           </dependency>
           <dependency>
               <groupId>com.amazonaws</groupId>
               <artifactId>aws-lambda-java-events</artifactId>
               <version>3.11.1</version>
           </dependency>
     </dependencies>
   <build>
       <plugins>
           <plugin>
               <groupId>org.codehaus.mojo</groupId>
               <artifactId>aspectj-maven-plugin</artifactId>
               <version>1.14.0</version>
               <configuration>
                   <source>${maven.compiler.source}</source>
                   <target>${maven.compiler.target}</target>
                   <complianceLevel>${maven.compiler.target}</complianceLevel>
                   <aspectLibraries>
                       <aspectLibrary>
                           <groupId>software.amazon.lambda</groupId>
                           <artifactId>powertools-tracing</artifactId>
                       </aspectLibrary>
                       <aspectLibrary>
                           <groupId>software.amazon.lambda</groupId>
                           <artifactId>powertools-metrics</artifactId>
                       </aspectLibrary>
                       <aspectLibrary>
                           <groupId>software.amazon.lambda</groupId>
                           <artifactId>powertools-logging</artifactId>
                       </aspectLibrary>
                   </aspectLibraries>
               </configuration>
               <executions>
                   <execution>
                       <goals>
                           <goal>compile</goal>
                       </goals>
                   </execution>
               </executions>
           </plugin>
           <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-shade-plugin</artifactId>
                   <version>3.4.1</version>
                   <executions>
                       <execution>
                           <phase>package</phase>
                           <goals>
                               <goal>shade</goal>
                           </goals>
                           <configuration>
                               <transformers>
                                   <transformer
                                           implementation="com.github.edwgiz.maven_shade_plugin.log4j2_cache_transformer.PluginsCacheFileTransformer">
                                   </transformer>
                               </transformers>
                               <createDependencyReducedPom>false</createDependencyReducedPom>
                               <finalName>function</finalName>
   
                           </configuration>
                       </execution>
                   </executions>
                   <dependencies>
                       <dependency>
                           <groupId>com.github.edwgiz</groupId>
                           <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
                           <version>2.15</version>
                       </dependency>
                   </dependencies>
           </plugin>
       </plugins>
   </build>
   </project>
   ```

1. Crie o diretório `hello-world\app\src\main\resource` e crie `log4j.xml` para a configuração do log.

   ```
   mkdir -p src/main/resource
   cd src/main/resource
   touch log4j.xml
   ```

1. Abra `log4j.xml` e adicione o código a seguir.

   ```
   <?xml version="1.0" encoding="UTF-8"?>
   <Configuration>
       <Appenders>
           <Console name="JsonAppender" target="SYSTEM_OUT">
               <JsonTemplateLayout eventTemplateUri="classpath:LambdaJsonLayout.json" />
           </Console>
       </Appenders>
       <Loggers>
           <Logger name="JsonLogger" level="INFO" additivity="false">
               <AppenderRef ref="JsonAppender"/>
           </Logger>
           <Root level="info">
               <AppenderRef ref="JsonAppender"/>
           </Root>
       </Loggers>
   </Configuration>
   ```

1. Abra o `App.java` partir do diretório `hello-world\app\Function\src\main\java\helloworld` e substitua o código existente pelo código a seguir. Este é o código da função do Lambda.

   ```
   package helloworld;
   
   import java.io.BufferedReader;
   import java.io.IOException;
   import java.io.InputStreamReader;
   import java.net.URL;
   import java.util.HashMap;
   import java.util.Map;
   import java.util.stream.Collectors;
   
   import com.amazonaws.services.lambda.runtime.Context;
   import com.amazonaws.services.lambda.runtime.RequestHandler;
   import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
   import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
   import org.apache.logging.log4j.LogManager;
   import org.apache.logging.log4j.Logger;
   import software.amazon.lambda.powertools.logging.Logging;
   import software.amazon.lambda.powertools.metrics.Metrics;
   import software.amazon.lambda.powertools.tracing.CaptureMode;
   import software.amazon.lambda.powertools.tracing.Tracing;
   
   import static software.amazon.lambda.powertools.tracing.CaptureMode.*;
   
   /**
    * Handler for requests to Lambda function.
    */
   public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
       Logger log = LogManager.getLogger(App.class);
   
   
       @Logging(logEvent = true)
       @Tracing(captureMode = DISABLED)
       @Metrics(captureColdStart = true)
       public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
           Map<String, String> headers = new HashMap<>();
           headers.put("Content-Type", "application/json");
           headers.put("X-Custom-Header", "application/json");
   
           APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent()
                   .withHeaders(headers);
           try {
               final String pageContents = this.getPageContents("https://checkip.amazonaws.com");
               String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents);
   
               return response
                       .withStatusCode(200)
                       .withBody(output);
           } catch (IOException e) {
               return response
                       .withBody("{}")
                       .withStatusCode(500);
           }
       }
       @Tracing(namespace = "getPageContents")
       private String getPageContents(String address) throws IOException {
           log.info("Retrieving {}", address);
           URL url = new URL(address);
           try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) {
               return br.lines().collect(Collectors.joining(System.lineSeparator()));
           }
       }
   }
   ```

1. Abra o `HelloWorldStack.java` partir do diretório `hello-world\src\main\java\com\myorg` e substitua o código existente pelo código a seguir. Esse código usa o [construtor Lambda](https://docs.aws.amazon.com/cdk/api/v1/java/aws_cdk.aws_lambda.html) e o [construtor ApiGatewayv2](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigatewayv2-readme.html) para criar uma API REST e uma função do Lambda.

   ```
   package com.myorg;
   
   import software.amazon.awscdk.*;
   import software.amazon.awscdk.services.apigatewayv2.alpha.*;
   import software.amazon.awscdk.services.apigatewayv2.integrations.alpha.HttpLambdaIntegration;
   import software.amazon.awscdk.services.apigatewayv2.integrations.alpha.HttpLambdaIntegrationProps;
   import software.amazon.awscdk.services.lambda.Code;
   import software.amazon.awscdk.services.lambda.Function;
   import software.amazon.awscdk.services.lambda.FunctionProps;
   import software.amazon.awscdk.services.lambda.Runtime;
   import software.amazon.awscdk.services.lambda.Tracing;
   import software.amazon.awscdk.services.logs.RetentionDays;
   import software.amazon.awscdk.services.s3.assets.AssetOptions;
   import software.constructs.Construct;
   
   import java.util.Arrays;
   import java.util.List;
   
   import static java.util.Collections.singletonList;
   import static software.amazon.awscdk.BundlingOutput.ARCHIVED;
   
   public class HelloWorldStack extends Stack {
       public HelloWorldStack(final Construct scope, final String id) {
           this(scope, id, null);
       }
   
       public HelloWorldStack(final Construct scope, final String id, final StackProps props) {
           super(scope, id, props);
   
           List<String> functionPackagingInstructions = Arrays.asList(
                   "/bin/sh",
                   "-c",
                   "cd Function " +
                           "&& mvn clean install " +
                           "&& cp /asset-input/Function/target/function.jar /asset-output/"
           );
           BundlingOptions.Builder builderOptions = BundlingOptions.builder()
                   .command(functionPackagingInstructions)
                   .image(Runtime.JAVA_11.getBundlingImage())
                   .volumes(singletonList(
                           // Mount local .m2 repo to avoid download all the dependencies again inside the container
                           DockerVolume.builder()
                                   .hostPath(System.getProperty("user.home") + "/.m2/")
                                   .containerPath("/root/.m2/")
                                   .build()
                   ))
                   .user("root")
                   .outputType(ARCHIVED);
   
           Function function = new Function(this, "Function", FunctionProps.builder()
                   .runtime(Runtime.JAVA_11)
                   .code(Code.fromAsset("app", AssetOptions.builder()
                           .bundling(builderOptions
                                   .command(functionPackagingInstructions)
                                   .build())
                           .build()))
                   .handler("helloworld.App::handleRequest")
                   .memorySize(1024)
                   .tracing(Tracing.ACTIVE)
                   .timeout(Duration.seconds(10))
                   .logRetention(RetentionDays.ONE_WEEK)
                   .build());
   
           HttpApi httpApi = new HttpApi(this, "sample-api", HttpApiProps.builder()
                   .apiName("sample-api")
                   .build());
   
           httpApi.addRoutes(AddRoutesOptions.builder()
                   .path("/")
                   .methods(singletonList(HttpMethod.GET))
                   .integration(new HttpLambdaIntegration("function", function, HttpLambdaIntegrationProps.builder()
                           .payloadFormatVersion(PayloadFormatVersion.VERSION_2_0)
                           .build()))
                   .build());
   
           new CfnOutput(this, "HttpApi", CfnOutputProps.builder()
                   .description("Url for Http Api")
                   .value(httpApi.getApiEndpoint())
                   .build());
       }
   }
   ```

1. Abra o `pom.xml` partir do diretório `hello-world` e substitua o código existente pelo código a seguir.

   ```
   <?xml version="1.0" encoding="UTF-8"?>
   <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
            xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <modelVersion>4.0.0</modelVersion>
   
       <groupId>com.myorg</groupId>
       <artifactId>hello-world</artifactId>
       <version>0.1</version>
   
       <properties>
           <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
           <cdk.version>2.70.0</cdk.version>
           <constructs.version>[10.0.0,11.0.0)</constructs.version>
           <junit.version>5.7.1</junit.version>
       </properties>
   
       <build>
           <plugins>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-compiler-plugin</artifactId>
                   <version>3.8.1</version>
                   <configuration>
                       <source>1.8</source>
                       <target>1.8</target>
                   </configuration>
               </plugin>
   
               <plugin>
                   <groupId>org.codehaus.mojo</groupId>
                   <artifactId>exec-maven-plugin</artifactId>
                   <version>3.0.0</version>
                   <configuration>
                       <mainClass>com.myorg.HelloWorldApp</mainClass>
                   </configuration>
               </plugin>
           </plugins>
       </build>
   
       <dependencies>
           <!-- AWS Cloud Development Kit -->
           <dependency>
               <groupId>software.amazon.awscdk</groupId>
               <artifactId>aws-cdk-lib</artifactId>
               <version>${cdk.version}</version>
           </dependency>
           <dependency>
               <groupId>software.constructs</groupId>
               <artifactId>constructs</artifactId>
               <version>${constructs.version}</version>
           </dependency>
           <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter</artifactId>
             <version>${junit.version}</version>
             <scope>test</scope>
           </dependency>
           <dependency>
               <groupId>software.amazon.awscdk</groupId>
               <artifactId>apigatewayv2-alpha</artifactId>
               <version>${cdk.version}-alpha.0</version>
           </dependency>
           <dependency>
               <groupId>software.amazon.awscdk</groupId>
               <artifactId>apigatewayv2-integrations-alpha</artifactId>
               <version>${cdk.version}-alpha.0</version>
           </dependency>
       </dependencies>
   </project>
   ```

1. Verifique se você está no diretório `hello-world` e implante a sua aplicação.

   ```
   cdk deploy
   ```

1. Obtenha o URL da aplicação implantada:

   ```
   aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?OutputKey==`HttpApi`].OutputValue' --output text
   ```

1. Invoque o endpoint da API:

   ```
   curl -X GET <URL_FROM_PREVIOUS_STEP>
   ```

   Se tiver êxito, você verá esta resposta:

   ```
   {"message":"hello world"}
   ```

1. Para obter os rastreamentos da função, execute [sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html).

   ```
   sam traces
   ```

   A saída de rastreamento se parece com:

   ```
   New XRay Service Graph
     Start time: 2025-02-03 14:59:50+00:00
     End time: 2025-02-03 14:59:50+00:00
     Reference Id: 0 - (Root) AWS::Lambda - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [1]
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0.924
     Reference Id: 1 - AWS::Lambda::Function - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: []
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0.016
     Reference Id: 2 - client - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [0]
      Summary_statistics:
        - total requests: 0
        - ok count(2XX): 0
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0
   
   XRay Event [revision 1] at (2025-02-03T14:59:50.204000) with id (1-63dd2166-434a12c22e1307ff2114f299) and duration (0.924s)
    - 0.924s - sam-app-HelloWorldFunction-YBg8yfYtOc9j [HTTP: 200]
    - 0.016s - sam-app-HelloWorldFunction-YBg8yfYtOc9j
      - 0.739s - Initialization
      - 0.016s - Invocation
        - 0.013s - ## lambda_handler
          - 0.000s - ## app.hello
      - 0.000s - Overhead
   ```

1. Este é um endpoint de API pública que é acessado pela Internet. Recomendamos excluir o endpoint após o teste.

   ```
   cdk destroy
   ```

## Usar o ADOT para instrumentar funções do Java
<a name="java-adot"></a>

O ADOT fornece [camadas](chapter-layers.md) do Lambda totalmente gerenciadas que empacotam tudo o que você precisa para coletar dados de telemetria usando o SDK do OTel. Ao consumir essa camada, é possível instrumentar suas funções Lambda sem precisar modificar nenhum código de função. Você também pode configurar sua camada para fazer a inicialização personalizada do OTel. Para obter mais informações, consulte [Custom configuration for the ADOT Collector on Lambda](https://aws-otel.github.io/docs/getting-started/lambda#custom-configuration-for-the-adot-collector-on-lambda) (Configuração personalizada para o ADOT Collector no Lambda) na documentação do ADOT.

Para runtimes do Java, é possível escolher entre duas camadas para consumir:
+ **Camada do Lambda gerenciada pela AWS para ADOT Java (agente de instrumentação automática)**: esta camada transforma automaticamente o código da função na inicialização para coletar dados de rastreamento. Para obter instruções detalhadas sobre como consumir essa camada junto com o agente Java do ADOT, consulte [Suporte do AWS Distro for OpenTelemetry Lambda para Java (agente de instrumentação automática)](https://aws-otel.github.io/docs/getting-started/lambda/lambda-java-auto-instr), na documentação do ADOT.
+ **Camada Lambda gerenciada pela AWS para ADOT Java**: esta camada também fornece instrumentação integrada para funções Lambda, mas requer algumas alterações manuais de código para inicializar o SDK do OTel. Para obter instruções detalhadas sobre como consumir essa camada, consulte [Suporte do AWS Distro for OpenTelemetry Lambda para Java](https://aws-otel.github.io/docs/getting-started/lambda/lambda-java), na documentação do ADOT.

## Usar o SDK do X-Ray para instrumentar suas funções Java
<a name="java-xray-sdk"></a>

Para registrar dados sobre chamadas que sua função faz para outros recursos e serviços em sua aplicação, adicione o X-Ray SDK for Java à sua configuração de compilação. O exemplo a seguir mostra uma configuração de compilação do Gradle que inclui as bibliotecas que ativam a instrumentação automática de clientes do AWS SDK for Java 2.x.

**Example [build.gradle](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java/build.gradle): rastrear dependências**  

```
dependencies {
    implementation platform('software.amazon.awssdk:bom:2.16.1')
    implementation platform('com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0')
    ...
    implementation 'com.amazonaws:aws-xray-recorder-sdk-core'
    implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk'
    implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2-instrumentor'
    ...
}
```

Depois de adicionar as dependências corretas e fazer as devidas mudanças de código, ative o rastreamento na configuração da sua função usando o console do Lambda ou a API.

## Ativar o rastreamento com o console do Lambda
<a name="java-tracing-console"></a>

Para alternar o rastreamento ativo na sua função do Lambda usando o console, siga as etapas abaixo:

**Para ativar o rastreamento ativo**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha uma função.

1. Escolha **Configuration** (Configuração) e depois **Monitoring and operations tools** (Ferramentas de monitoramento e operações).

1. Em **Ferramentas de monitoramento adicionais**, selecione **Editar**.

1. Em **CloudWatch Application Signals e AWS X-Ray**, escolha **Habilitar** para **Rastreamentos do serviço Lambda**.

1. Selecione **Salvar**.

## Ativar o rastreamento com a API do Lambda
<a name="java-tracing-api"></a>

Configure o rastreamento na sua função do Lambda com a AWS CLI ou o AWS SDK, usando as seguintes operações de API:
+ [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)
+ [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html)
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)

O exemplo de comando da AWS CLI a seguir habilita o rastreamento ativo em uma função chamada **my-function**.

```
aws lambda update-function-configuration --function-name my-function \
--tracing-config Mode=Active
```

O modo de rastreamento faz parte da configuração específica da versão quando você publica uma versão da função. Não é possível alterar o modo de rastreamento em uma versão publicada.

## Ativar o rastreamento com o CloudFormation
<a name="java-tracing-cloudformation"></a>

Para ativar o rastreamento ativo em um recurso `AWS::Lambda::Function` em um modelo do CloudFormation, use a propriedade `TracingConfig`.

**Example [function-inline.yml](https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/templates/function-inline.yml): configuração de rastreamento**  

```
Resources:
  function:
    Type: [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)
    Properties:
      TracingConfig:
        Mode: Active
      ...
```

Para um recurso do AWS Serverless Application Model (AWS SAM) `AWS::Serverless::Function`, use a propriedade `Tracing`.

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml): configuração de rastreamento**  

```
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      Tracing: Active
      ...
```

## Interpretar um rastreamento do X-Ray
<a name="java-tracing-interpretation"></a>

Sua função precisa de permissão para carregar dados de rastreamento no X-Ray. Quando você ativa o rastreamento ativo no console do Lambda, o Lambda adiciona as permissões necessárias à [função de execução](lambda-intro-execution-role.md) da função. Caso contrário, adicione a política [AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess) à função de execução.

Após configurar o rastreamento ativo, você pode observar solicitações específicas por meio da aplicação. O [grafo de serviço do X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph) exibe informações sobre sua aplicação e todos os componentes. O exemplo a seguir mostra uma aplicação com duas funções. A função principal processa eventos e, às vezes, retorna erros. A segunda função de cima para baixo processa erros que aparecem no primeiro grupo de logs e usa o AWS SDK para chamar o X-Ray, o Amazon Simple Storage Service (Amazon S3) e o Amazon CloudWatch Logs.

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/sample-errorprocessor-servicemap.png)


O X-Ray não rastreia todas as solicitações para sua aplicação. O X-Ray aplica um algoritmo de amostragem para garantir que o rastreamento seja eficiente, enquanto ainda fornece uma amostra representativa das solicitações. A taxa de amostragem é uma solicitação por segundo e 5% de solicitações adicionais. Você não pode configurar a taxa de amostragem do X-Ray para suas funções.

No X-Ray, um *rastreamento* registra informações sobre uma solicitação que é processada por um ou mais *serviços*. O Lambda registra dois segmentos por rastreamento, o que cria dois nós no gráfico de serviços. A imagem a seguir destaca esses dois nós:

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/xray-servicemap-function.png)


O primeiro nó à esquerda representa o serviço do Lambda, que recebe a solicitação de invocação. O segundo nó representa a sua função do Lambda específica. O exemplo a seguir mostra um rastreamento com esses dois segmentos. Ambos têm o nome **my-function**, mas um tem a origem `AWS::Lambda` e o outro, a origem `AWS::Lambda::Function`. Se o segmento `AWS::Lambda` mostrar um erro, o serviço Lambda teve um problema. Se o segmento `AWS::Lambda::Function` mostrar um erro, sua função teve um problema.

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/V2_sandbox_images/my-function-2-v1.png)


Este exemplo expande o segmento `AWS::Lambda::Function` para mostrar seus três subsegmentos.

**nota**  
A AWS atualmente está implementando alterações no serviço Lambda. Devido a essas alterações, você pode ver pequenas diferenças entre a estrutura e o conteúdo das mensagens de log do sistema e os segmentos de rastreamento emitidos por diferentes funções do Lambda na sua Conta da AWS.  
O exemplo de rastreamento mostrado aqui ilustra o segmento de função no estilo antigo. As diferenças entre os segmentos no estilo antigo e no estilo novo são descritas nos próximos parágrafos.  
Essas alterações serão implementadas durante as próximas semanas, e todas as funções em todas as Regiões da AWS, exceto nas regiões China e GovCloud, passarão a usar o novo formato de mensagens de log e segmentos de rastreamento.

O segmento de função no estilo antigo contém os seguintes subsegmentos:
+ **Inicialização**: representa o tempo gasto carregando a função e executando o [código de inicialização](foundation-progmodel.md). Esse subsegmento aparece somente para o primeiro evento que cada instância da função processa.
+ **Invocação**: representa o tempo gasto na execução do código do manipulador.
+ **Sobrecarga**: representa o tempo gasto pelo runtime do Lambda preparando-se para lidar com o próximo evento.

O segmento de função no estilo novo não contém um subsegmento `Invocation`. Em vez disso, os subsegmentos dos clientes são anexados diretamente ao segmento da função. Para obter mais informações sobre a estrutura dos segmentos de função no estilo antigo e no estilo novo, consulte [Noções básicas sobre rastreamentos do X-Ray](services-xray.md#services-xray-traces).

**nota**  
As funções [Lambda SnapStart](snapstart.md) também incluem um subsegmento `Restore`. O subsegmento `Restore` mostra o tempo necessário para o Lambda restaurar um snapshot, carregar o runtime e executar qualquer [hook de runtime](snapstart-runtime-hooks.md) after-restore. O processo de restauração de snapshots pode incluir o tempo gasto em atividades fora da MicroVM. Esse tempo é relatado no subsegmento `Restore`. Você não é cobrado pelo tempo gasto fora da microVM para restaurar um snapshot.

Você também pode instrumentar clientes HTTP, registrar consultas SQL e criar subsegmentos personalizados com anotações e metadados. Para obter mais informações, consulte [SDK do AWS X-Ray for Java](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java.html) no *Guia do desenvolvedor do AWS X-Ray*.

**Preços**  
Você pode usar o rastreamento do X-Ray gratuitamente todos os meses até determinado limite como parte do nível gratuito da AWS. Além do limite, o X-Ray cobra por armazenamento e recuperação de rastreamento. Para obter mais informações, consulte [Preços do AWS X-Ray](https://aws.amazon.com/xray/pricing/).

## Armazenar dependências de runtime em uma camada (SDK do X-Ray)
<a name="java-tracing-layers"></a>

Se você usar o X-Ray SDK para instrumentar os clientes do AWS SDK com seu código de função, seu pacote de implantação poderá se tornar bastante grande. Para evitar o upload de dependências de runtime todas as vezes que você atualizar seu código de função, empacote o SDK do X-Ray em uma [camada do Lambda](chapter-layers.md).

O exemplo a seguir mostra um recurso `AWS::Serverless::LayerVersion` que armazena o AWS SDK para Java e o X-Ray SDK for Java.

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-java/template.yml): camada de dependências**  

```
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      CodeUri: build/distributions/blank-java.zip
      Tracing: Active
      Layers:
        - !Ref libs
      ...
  libs:
    Type: [AWS::Serverless::LayerVersion](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-layerversion.html)
    Properties:
      LayerName: blank-java-lib
      Description: Dependencies for the blank-java sample app.
      ContentUri: build/blank-java-lib.zip
      CompatibleRuntimes:
        - java25
```

Com essa configuração, você atualizará a camada de biblioteca somente se alterar as dependências de runtime. Já que o pacote de implantação de função inclui apenas o seu código, isso pode ajudar a reduzir o tempo de upload.

A criação de uma camada de dependências requer alterações de configuração de compilação para gerar o arquivo de camada antes da implantação. Para obter um exemplo funcional, consulte a aplicação de exemplo [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic) no GitHub.

## Rastreamento do X-Ray em aplicações de exemplo (SDK do X-Ray)
<a name="java-tracing-samples"></a>

O repositório do GitHub para este guia inclui aplicações de exemplo que demonstram o uso do rastreamento do X-Ray. Cada aplicativo de exemplo inclui scripts para fácil implantação e limpeza, um modelo do AWS SAM e recursos de suporte.

**Aplicações de exemplo do Lambda em Java**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java): uma função Java que demonstra como você pode usar o Lambda para processar pedidos. Essa função ilustra como definir e desserializar um objeto de evento de entrada personalizado, usar o AWS SDK e gerar logs de saída.
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic): uma coleção de funções Java mínimas com testes de unidade e configuração de registro em log variável.
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events): uma coleção de funções do Java contendo código básico sobre como lidar com eventos de vários serviços, como o Amazon API Gateway, o Amazon SQS e o Amazon Kinesis. Essas funções usam a versão mais recente da biblioteca [aws-lambda-java-events](java-package.md) (3.0.0 e versões mais recentes). Estes exemplos não exigem o AWS SDK como dependência.
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java): uma função em Java que processa eventos de notificação do Amazon S3 e usa a Java Class Library (JCL) para criar miniaturas de arquivos de imagem enviados por upload.
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java): uma função Java que ilustra como usar uma camada do Lambda para empacotar dependências separadamente do código da função principal.

Todas as aplicações de exemplo têm rastreamento ativo habilitado para funções do Lambda. Por exemplo, a aplicação `s3-java` mostra instrumentação automática de clientes AWS SDK for Java 2.x, gerenciamento de segmentos para testes, subsegmentos personalizados e o uso de camadas do Lambda para armazenar dependências de runtime.

# Aplicativos de exemplo Java para o AWS Lambda
<a name="java-samples"></a>

O repositório do GitHub para este guia inclui aplicativos de exemplo que demonstram o uso do Java no AWS Lambda. Cada aplicativo de exemplo inclui scripts para fácil implantação e limpeza, um modelo do CloudFormation e recursos de suporte.

**Aplicações de exemplo do Lambda em Java**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java): uma função Java que demonstra como você pode usar o Lambda para processar pedidos. Essa função ilustra como definir e desserializar um objeto de evento de entrada personalizado, usar o AWS SDK e gerar logs de saída.
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic): uma coleção de funções Java mínimas com testes de unidade e configuração de registro em log variável.
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events): uma coleção de funções do Java contendo código básico sobre como lidar com eventos de vários serviços, como o Amazon API Gateway, o Amazon SQS e o Amazon Kinesis. Essas funções usam a versão mais recente da biblioteca [aws-lambda-java-events](java-package.md) (3.0.0 e versões mais recentes). Estes exemplos não exigem o AWS SDK como dependência.
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java): uma função em Java que processa eventos de notificação do Amazon S3 e usa a Java Class Library (JCL) para criar miniaturas de arquivos de imagem enviados por upload.
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java): uma função Java que ilustra como usar uma camada do Lambda para empacotar dependências separadamente do código da função principal.

**Executar estruturas Java populares no Lambda**
+ [spring-cloud-function-samples](https://github.com/spring-cloud/spring-cloud-function/tree/3.2.x/spring-cloud-function-samples/function-sample-aws): um exemplo da Spring que mostra como usar a estrutura [Spring Cloud Function](https://spring.io/projects/spring-cloud-function) para criar funções do AWS Lambda. 
+ [Demonstração da aplicação Spring Boot sem servidor](https://github.com/aws-samples/serverless-java-frameworks-samples/tree/main/springboot): um exemplo que mostra como configurar uma aplicação Spring Boot típica em um runtime Java gerenciado com e sem o SnapStart, ou como uma imagem nativa do GraalVM com um runtime personalizado.
+ [Demonstração da aplicação Micronaut sem servidor](https://github.com/aws-samples/serverless-java-frameworks-samples/tree/main/micronaut): um exemplo que mostra como usar o Micronaut em um runtime Java gerenciado com e sem o SnapStart, ou como uma imagem nativa do GraalVM com um runtime personalizado. Saiba mais nos [guias do Micronaut/Lambda](https://guides.micronaut.io/latest/tag-lambda.html).
+ [Demonstração da aplicação Quarkus sem servidor](https://github.com/aws-samples/serverless-java-frameworks-samples/tree/main/quarkus): um exemplo que mostra como usar o Quarkus em um runtime Java gerenciado com e sem o SnapStart, ou como uma imagem nativa do GraalVM com um runtime personalizado. [Saiba mais no [guia do Quarkus/Lambda](https://quarkus.io/guides/aws-lambda) e no guia do Quarkus/SnapStart](https://quarkus.io/guides/aws-lambda-snapstart).

Se você ainda é iniciante com as funções do Lambda em Java, comece com os exemplos de `java-basic`. Para começar a usar as origens de eventos do Lambda, consulte os exemplos de `java-events`. Os dois exemplos mostram o uso das bibliotecas Java do Lambda, das variáveis de ambiente, do AWS SDK e do SDK do AWS X-Ray. Estes exemplos requerem configuração mínima e podem ser implantados pela linha de comando em menos de um minuto.