

# Creación de funciones de Lambda con Java
<a name="lambda-java"></a>

Puede ejecutar código Java en AWS Lambda. Lambda proporciona [tiempos de ejecución](lambda-runtimes.md) para Java que ejecutan código para procesar eventos. El código se ejecuta en un entorno de Amazon Linux que incluye las credenciales de AWS de un rol de AWS Identity and Access Management (IAM) administrado por usted.

Lambda admite los siguientes tiempos de ejecución de Java.<a name="java-runtimes"></a>


| Nombre | Identificador | Sistema operativo | Fecha de baja | Bloqueo de la función Crear | Bloqueo de la función Actualizar | 
| --- | --- | --- | --- | --- | --- | 
|  Java 25  |  `java25`  |  Amazon Linux 2023  |   30 de junio de 2029   |   31 de julio de 2029   |   31 de agosto de 2029   | 
|  Java 21  |  `java21`  |  Amazon Linux 2023  |   30 de junio de 2029   |   31 de julio de 2029   |   31 de agosto de 2029   | 
|  Java 17  |  `java17`  |  Amazon Linux 2  |   30 de junio de 2027   |   31 de julio de 2027   |   31 de agosto de 2027   | 
|  Java 11  |  `java11`  |  Amazon Linux 2  |   30 de junio de 2027   |   31 de julio de 2027   |   31 de agosto de 2027   | 
|  Java 8  |  `java8.al2`  |  Amazon Linux 2  |   30 de junio de 2027   |   31 de julio de 2027   |   31 de agosto de 2027   | 

AWS proporciona las siguientes bibliotecas de funciones de Java. Estas bibliotecas están disponibles en el [repositorio central de 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) (obligatoria): define interfaces de métodos de controlador y el objeto contextual que el entorno de ejecución pasa al controlador. Si define sus propios tipos de entrada, esta es la única biblioteca que necesita.
+ [com.amazonaws:aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-events): tipos de entrada de eventos procedentes de servicios que invocan funciones de Lambda.
+ [com.amazonaws:aws-lambda-java-log4j2](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-log4j2): una biblioteca de appender de Log4j 2 para Apache que puede usar para agregar el ID solicitado en la invocación actual a los [registros de funciones](java-logging.md).
+ [AWS SDK para Java 2.0](https://github.com/aws/aws-sdk-java-v2): el SDK oficial de AWS para el lenguaje de programación Java.

Agregue estas bibliotecas a la definición de la compilación de la siguiente manera:

------
#### [ 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**  
No utilice componentes privados (por ejemplo, campos, métodos o clases) de la API de JDK. Los componentes de la API que no son públicos pueden cambiar o eliminarse en cualquier actualización, y la aplicación dejará de funcionar.

**Para crear una función Java**

1. Abra la [consola de Lambda](https://console.aws.amazon.com/lambda).

1. Seleccione **Creación de función**.

1. Configure los siguientes ajustes:
   + En **Nombre de la función**: ingrese el nombre de la función.
   + En **Tiempo de ejecución**, elija **Java 25**.

1. Elija **Crear función**.

La consola crea una función de Lambda con una clase de controlador denominada `Hello`. Dado que Java es un lenguaje compilado, no puede ver ni editar el código fuente en la consola de Lambda, pero puede modificar su configuración, invocarla y configurar disparadores.

**nota**  
Para comenzar con el desarrollo de aplicaciones en su entorno local, implemente una de las [aplicaciones de ejemplo](java-samples.md) disponibles en el repositorio de GitHub de esta guía.

La clase `Hello` cuenta con una función denominada `handleRequest` que toma un objeto de evento y un objeto context. Esta es la [función de controlador](java-handler.md) a la que llama Lambda cuando se invoca la función. El tiempo de ejecución de la función de Java obtiene los eventos de invocación de Lambda y se los pasa al controlador. En la configuración de función, el valor de controlador es `example.Hello::handleRequest`.

Para actualizar el código de la función, cree un paquete de implementación, que es un archivo .zip que contiene el código de la función. A medida que avanza su función de desarrollo, querrá almacenar su código de función en el control del código fuente, agregar bibliotecas y automatizar las implementaciones. Comience [creando un paquete de implementación](java-package.md) y actualizando el código en la línea de comandos.

El tiempo de ejecución de la función pasa un objeto context al controlador, además del evento de invocación. El [objeto context](java-context.md) contiene información adicional acerca de la invocación, la función y el entorno de ejecución. Hay más información disponible en las variables de entorno.

Su función de Lambda tiene un grupo de registros de Registros de CloudWatch. El tiempo de ejecución de la función envía detalles de cada invocación a Registros de CloudWatch. Se transmite cualquier [registro que su función genere](java-logging.md) durante la invocación. Si su función devuelve un error, Lambda formatea el error y lo devuelve al invocador.

**Topics**
+ [Definir el controlador de las funciones de Lambda en Java](java-handler.md)
+ [Implementar funciones de Lambda Java con archivos de archivo .zip o JAR](java-package.md)
+ [Implementar funciones Java Lambda con imágenes de contenedor](java-image.md)
+ [Uso de capas para funciones de Lambda en Java](java-layers.md)
+ [Personalización de la serialización para las funciones Java de Lambda](java-custom-serialization.md)
+ [Personalice el comportamiento de inicio del tiempo de ejecución de Java para funciones de Lambda](java-customization.md)
+ [Uso del objeto de contexto Lambda para recuperar información de funciones de Java](java-context.md)
+ [Registro y supervisión de las funciones de Lambda de Java](java-logging.md)
+ [Instrumentación del código Java en AWS Lambda](java-tracing.md)
+ [Aplicaciones de ejemplo de Java para AWS Lambda](java-samples.md)

# Definir el controlador de las funciones de Lambda en Java
<a name="java-handler"></a>

El *controlador* de la función de Lambda es el método del código de la función que procesa eventos. Cuando se invoca una función, Lambda ejecuta el método del controlador. La función se ejecuta hasta que el controlador devuelve una respuesta, se cierra o se agota el tiempo de espera.

En esta página, se describe cómo trabajar con los controladores de funciones de Lambda en Java, incluidas opciones para la configuración del proyecto, las convenciones de nomenclatura y las prácticas recomendadas. Esta página también incluye el ejemplo de una función de Lambda de Java que recibe información sobre un pedido, genera un recibo en un archivo de texto y coloca este archivo en un bucket de Amazon Simple Storage Service (Amazon S3). Para obtener información sobre cómo implementar la función después de escribirla, consulte [Implementar funciones de Lambda Java con archivos de archivo .zip o JAR](java-package.md) o [Implementar funciones Java Lambda con imágenes de contenedor](java-image.md).

**Topics**
+ [Configuración del proyecto de controlador de Java](#java-handler-setup)
+ [Ejemplo de código de función de Lambda de Java](#java-example-code)
+ [Definiciones de clase válidas para los controladores de Java](#java-handler-signatures)
+ [Convenciones de nomenclatura de controladores](#java-example-naming)
+ [Definición del objeto de evento de entrada y acceso a él](#java-handler-input)
+ [Acceso y uso del objeto de contexto de Lambda](#java-example-context)
+ [Uso de la versión 2 de AWS SDK para Java en el controlador](#java-example-sdk-usage)
+ [Acceso a las variables de entorno](#java-example-envvars)
+ [Uso del estado global](#java-handler-state)
+ [Prácticas recomendadas de codificación para las funciones de Lambda](#java-best-practices)

## Configuración del proyecto de controlador de Java
<a name="java-handler-setup"></a>

Cuando se trabaja con funciones de Lambda en Java, el proceso implica escribir el código, compilarlo e implementar los artefactos compilados en Lambda. Puede inicializar un proyecto de Lambda en Java de varias maneras. Por ejemplo, puede usar herramientas como el [Arquetipo de Maven para funciones de Lambda](https://github.com/aws/aws-sdk-java-v2/tree/master/archetypes/archetype-lambda), el [comando sam init de AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-init.html) o incluso una configuración de proyecto Java estándar en su IDE preferido, como IntelliJ IDEA o Visual Studio Code. Si lo prefiere, puede crear la estructura de archivos necesaria de forma manual.

Un proyecto típico de la función de Lambda en Java sigue esta estructura general:

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

Puede usar Maven o Gradle para crear su proyecto y administrar las dependencias.

La lógica del controlador principal de su función reside en un archivo Java ubicado en el directorio `src/main/java/example`. En el ejemplo de esta página, el nombre de este archivo es `OrderHandler.java`. Además de este archivo, puede incluir clases de Java adicionales según sea necesario. Al implementar la función en Lambda, asegúrese de especificar la clase de Java que contiene el método de controlador principal que Lambda debe invocar durante una invocación.

## Ejemplo de código de función de Lambda de Java
<a name="java-example-code"></a>

El siguiente ejemplo de código de función de Lambda de Java 21 recibe información sobre un pedido, genera un recibo en un archivo de texto y coloca este archivo en un bucket de Amazon S3.

**Example `OrderHandler.java`Función de Lambda**  

```
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 archivo `OrderHandler.java` contiene las siguientes secciones de código:
+ `package example`: en Java, puede ser cualquier cosa, pero debe coincidir con la estructura de directorio del proyecto. Aquí, usamos `package example` porque la estructura del directorio es `src/main/java/example`.
+ Instrucciones `import`: utilícelas para importar las clases de Java que requiere la función de Lambda.
+ `public class OrderHandler ...`: define la clase de Java y debe ser una [definición de clase válida](#java-handler-signatures).
+ `private static final S3Client S3_CLIENT ...`: inicializa un cliente S3 fuera de cualquiera de los métodos de la clase. Esto hace que Lambda ejecute este código durante la [fase de inicialización](lambda-runtime-environment.md#runtimes-lifecycle-ib).
+ `public record Order ...`: defina la forma del evento de entrada esperado en este [registro](https://openjdk.org/jeps/395) personalizado de Java.
+ `public String handleRequest(Order event, Context context)`: este es el **método del controlador principal**, que contiene la lógica principal de la aplicación.
+ `private void uploadReceiptToS3(...) {}`: este es un método auxiliar al que hace referencia el método del controlador principal `handleRequest`.

### Ejemplo de archivo build.gradle y pom.xml
<a name="java-gradle-maven-example"></a>

El siguiente archivo `build.gradle` o `pom.xml` acompaña esta función.

------
#### [ 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 función se ejecute correctamente, su [rol de ejecución](lambda-intro-execution-role.md) debe permitir la acción `s3:PutObject`. Además, asegúrese de definir la variable de entorno `RECEIPT_BUCKET`. Tras una invocación correcta, el bucket de Amazon S3 debe contener un archivo de recibo.

**nota**  
Es posible que esta función requiera configuración adicional para ejecutarse correctamente sin que se agote el tiempo de espera. Recomendamos configurar 256 MB de memoria y un tiempo de espera de 10 segundos. La primera invocación puede demorar más tiempo debido a un [arranque en frío](lambda-runtime-environment.md#cold-start-latency). Las invocaciones posteriores deberían ejecutarse mucho más rápido, ya que se reutiliza el entorno de ejecución.

## Definiciones de clase válidas para los controladores de Java
<a name="java-handler-signatures"></a>

Para definir su clase, la biblioteca [aws-lambda-java-core](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-core) define dos interfaces para los métodos de controlador. Utilice las interfaces proporcionadas para simplificar la configuración y validar la firma del método del controlador en tiempo de compilación.
+ [ 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)

La interfaz `RequestHandler` es un tipo genérico que toma dos parámetros: el tipo de entrada y el tipo de salida. Los dos tipos deben ser objetos. En este ejemplo, nuestra clase `OrderHandler` implementa `RequestHandler<OrderHandler.Order, String>`. El tipo de entrada es el registro `Order` que definimos dentro de la clase y el tipo de salida es `String`.

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

Cuando se utiliza esta interfaz, el tiempo de ejecución de Java deserializa el evento en un objeto con el tipo de entrada y serializa la salida en texto. Utilice esta interfaz si la serialización integrada funcione con los tipos de entrada y salida.

Para usar su propia serialización, puede implementar la interfaz `RequestStreamHandler`. Con esta interfaz, Lambda pasa al controlador un flujo de entrada y otrp flujo de salida. El controlador lee los bytes de la secuencia de entrada, escribe en la secuencia de salida y devuelve void. Para ver un ejemplo de esto con el tiempo de ejecución de 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).

Si solo trabaja con tipos básicos y genéricos (es decir `String`, `Integer`, `List` o `Map`) en su función de Java, no necesita implementar una interfaz. Por ejemplo, si la función recibe una entrada `Map<String, String>` y devuelve un `String`, la definición de la clase y la firma del controlador pueden verse como el siguiente ejemplo:

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

Además, cuando no implementa una interfaz, el objeto de [contexto](java-context.md) es opcional. Por ejemplo, la definición de la clase y la firma del controlador pueden verse como el siguiente ejemplo:

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

## Convenciones de nomenclatura de controladores
<a name="java-example-naming"></a>

Para las funciones de Lambda en Java, si implementa la interfaz de `RequestHandler` o `RequestStreamHandler`, el método de su controlador principal debe tener `handleRequest` como nombre. Además, incluya la etiqueta `@Override` situada sobre el método `handleRequest`. Cuando implemente la función en Lambda, especifique el controlador principal en la configuración de la función en el siguiente formato:
+ *<package>*.*<Class>* – Por ejemplo, `example.OrderHandler`.

En el caso de las funciones de Lambda en Java que no implementan la interfaz de `RequestHandler` o `RequestStreamHandler`, es posible utilizar cualquier nombre para el controlador. Cuando implemente la función en Lambda, especifique el controlador principal en la configuración de la función en el siguiente formato:
+ *<package>*.*<Class>*::*<handler\$1method\$1name>* – Por ejemplo, `example.Handler::mainHandler`.

## Definición del objeto de evento de entrada y acceso a él
<a name="java-handler-input"></a>

El formato de entrada más común y estándar de las funciones de Lambda es JSON. En este ejemplo, la función espera una entrada similar a la siguiente:

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

Al trabajar con funciones de Lambda en Java 17 o versiones posteriores, puede definir la forma del evento de entrada esperado como un registro de Java. En este ejemplo, definimos un registro dentro de la clase `OrderHandler` para representar un objeto `Order`:

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

Este registro coincide con la forma de entrada esperada. Después de definir el registro, puede escribir una firma de controlador que incluya una entrada de JSON que se ajuste a la definición del registro. El tiempo de ejecución de Java deserializa automáticamente este JSON en un objeto Java. Ahora puede acceder a los campos del objeto. Por ejemplo, `event.orderId` recupera el valor de `orderId` de la entrada original.

**nota**  
Los registros de Java son una característica de los tiempos de ejecución de Java 17 y versiones posteriores únicamente. En todos los entornos de ejecución de Java, puede usar una clase para representar los datos de eventos. En esos casos, puede usar una biblioteca como [jackson](https://github.com/FasterXML/jackson) para deserializar las entradas de JSON.

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

Hay muchos eventos de entrada posibles para las funciones de Lambda en Java:
+ `Integer`, `Long`, `Double`, etc.: - El evento es un número sin formato adicional; por ejemplo, `3.5`. El tiempo de ejecución convierte el valor en un objeto del tipo especificado.
+ `String` – el evento es una cadena JSON, incluidas las comillas; por ejemplo, `“My string”`. El tiempo de ejecución convierte el valor en un objeto `String` sin comillas.
+ `List<Integer>`, `List<String>`, `List<Object>`, etc.: - El evento es una matriz JSON. El entorno de ejecución lo deserializa en un objeto del tipo especificado o una interfaz.
+ `InputStream`: el evento es cualquier tipo JSON. El entorno de ejecución pasa una secuencia de bytes del documento al controlador sin modificaciones. Usted deserializa la entrada y escribe la salida en una secuencia de salida.
+ Tipo de biblioteca: en el caso de los eventos enviados por otros servicios de AWS, utilice los tipos de la biblioteca [aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-events). Por ejemplo, si Amazon Simple Queue Service (SQS) invoca la función de Lambda, utilice el objeto `SQSEvent` como entrada.

## Acceso y uso del objeto de contexto de Lambda
<a name="java-example-context"></a>

El [objeto de contexto](java-context.md) de Lambda contiene información sobre la invocación, la función y el entorno de ejecución. En este ejemplo, el objeto de contexto es de tipo `com.amazonaws.services.lambda.runtime.Context` y es el segundo argumento de la función del controlador principal.

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

Si la clase implementa la interfaz [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) o [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), el objeto de contexto es un argumento obligatorio. De lo contrario, el objeto de contexto es opcional. Para obtener más información sobre las firmas de controlador válidas, consulte [Definiciones de clase válidas para los controladores de Java](#java-handler-signatures).

Si hace llamadas a otros servicios mediante el AWS SDK, el objeto de contexto es obligatorio en algunas áreas clave. Por ejemplo, para generar registros de funciones para Amazon CloudWatch, puede utilizar el método `context.getLogger()` a fin de obtener un objeto `LambdaLogger` para el registro. En este ejemplo, podemos usar el registrador para registrar un mensaje de error si el procesamiento falla por cualquier motivo:

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

Además del registro, también puede usar el objeto de contexto para supervisar las funciones. Para obtener más información acerca del objeto de contexto, consulte [Uso del objeto de contexto Lambda para recuperar información de funciones de Java](java-context.md).

## Uso de la versión 2 de AWS SDK para Java en el controlador
<a name="java-example-sdk-usage"></a>

A menudo, utilizará las funciones de Lambda para interactuar con otros recursos de AWS o actualizarlos. La forma más sencilla de interactuar con estos recursos es utilizar la versión 2 de AWS SDK para Java.

**nota**  
AWS SDK para Java (versión 1) está en modo de mantenimiento y está previsto que deje de ser compatible el 31 de diciembre de 2025. Le recomendamos que utilice únicamente la versión 2 de AWS SDK para Java de ahora en adelante.

Para agregar dependencias del SDK a su función, agréguelas al archivo `build.gradle` para Gradle o al archivo `pom.xml` para Maven. Le recomendamos que solo agregue las bibliotecas que necesite para su función. En el código de ejemplo anterior, utilizamos la biblioteca `software.amazon.awssdk.services.s3`. En Gradle, puede agregar esta dependencia agregando la siguiente línea en la sección de dependencias de `build.gradle`:

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

En Maven, agregue las siguientes líneas en la sección `<dependencies>` de `pom.xml`:

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

**nota**  
Es posible que esta no sea la versión más reciente del SDK. Elija la versión del SDK adecuada para la aplicación.

Luego, importe las dependencias directamente en la clase de Java:

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

El código de ejemplo inicializa un cliente de Amazon S3 de la siguiente manera:

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

En este ejemplo, inicializamos el cliente de Amazon S3 fuera de la función del controlador principal para evitar tener que inicializarlo cada vez que invocamos nuestra función. Después de inicializar el cliente del SDK, podrá usarlo para interactuar con otros servicios de AWS. El código de ejemplo llama a la API `PutObject` de Amazon S3 de la siguiente manera:

```
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)));
```

## Acceso a las variables de entorno
<a name="java-example-envvars"></a>

En el código del controlador, puede hacer referencia a cualquier [variable de entorno](configuration-envvars.md) mediante el método `System.getenv()`. En este ejemplo, hacemos referencia a la variable de entorno `RECEIPT_BUCKET` definida mediante la siguiente línea de código:

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

## Uso del estado global
<a name="java-handler-state"></a>

Lambda ejecuta su código estático y el constructor de clases durante la [fase de inicialización](lambda-runtime-environment.md#runtimes-lifecycle-ib) antes de invocar la función por primera vez. Los recursos que se crean durante la inicialización permanecen en la memoria entre las invocaciones, por lo que evita tener que crearlos cada vez que invoca la función.

En el código de ejemplo, el código de inicialización del cliente S3 está fuera del método del controlador principal. El tiempo de ejecución inicializa el cliente antes de que la función gestione su primer evento; por su parte, el cliente permanece disponible para su reutilización en todas las invocaciones.

## Prácticas recomendadas de codificación para las funciones de Lambda
<a name="java-best-practices"></a>

Siga las directrices de la siguiente lista para utilizar las prácticas recomendadas de codificación al crear sus funciones de Lambda:
+ **Separe el controlador de Lambda de la lógica del núcleo.** Esto le permite probar las distintas unidades de la función con mayor facilidad.
+ **Controle las dependencias del paquete de implementación de la función. ** El entorno de ejecución AWS Lambda contiene varias bibliotecas. Para disponer del conjunto más reciente de características y actualizaciones de seguridad, Lambda actualizará periódicamente estas bibliotecas. Estas actualizaciones pueden introducir cambios sutiles en el comportamiento de la función de Lambda. Para disponer de un control total de las dependencias que utiliza la función, empaquete todas las dependencias con el paquete de implementación. 
+ **Minimice la complejidad de las dependencias.** Son preferibles los marcos de trabajo más sencillos, ya que se cargan rápidamente al arrancar el [entorno de ejecución](lambda-runtime-environment.md). Por ejemplo, es preferible utilizar los marcos de trabajo de inserción de dependencias (IoC) de Java más sencillos, como [Dagger](https://google.github.io/dagger/) o [Guice](https://github.com/google/guice), que los más complejos, como [Spring Framework](https://github.com/spring-projects/spring-framework).
+ **Minimice el tamaño del paquete de implementación de acuerdo con las necesidades de su tiempo de ejecución. ** Esto reducirá la cantidad de tiempo que tarda el paquete de implementación en descargarse y desempaquetarse antes de la invocación. En las funciones creadas en Java, evite cargar toda la biblioteca de AWS SDK como parte del paquete de implementación. En lugar de ello, cree dependencias selectivas de los módulos que seleccionen los componentes del SDK que necesita (por ejemplo, DynamoDB, módulos del SDK de Amazon S3 y [bibliotecas básicas de Lambda](https://github.com/aws/aws-lambda-java-libs)).

**Reutilice el entorno de ejecución para mejorar el rendimiento de la función.** Inicialice los clientes de SDK y las conexiones de base de datos fuera del controlador de funciones y almacene localmente en caché los recursos estáticos en el directorio `/tmp`. Las invocaciones posteriores procesadas por la misma instancia de su función pueden reutilizar estos recursos. Esto ahorra costes al reducir el tiempo de ejecución de la función.

Para evitar posibles filtraciones de datos entre las invocaciones, no utilice el entorno de ejecución para almacenar datos de usuario, eventos u otra información con implicaciones de seguridad. Si su función se basa en un estado mutable que no se puede almacenar en la memoria dentro del controlador, considere crear una función independiente o versiones independientes de una función para cada usuario.

**Utilice una directiva keep-alive para mantener conexiones persistentes.** Lambda purga las conexiones inactivas a lo largo del tiempo. Si intenta reutilizar una conexión inactiva al invocar una función, se producirá un error de conexión. Para mantener la conexión persistente, use la directiva keep-alive asociada al tiempo de ejecución. Para ver un ejemplo, consulte [Reutilización de conexiones con Keep-Alive en Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html).

**Utilice [variables de entorno](configuration-envvars.md) para pasar parámetros operativos a su función.** Por ejemplo, si está escribiendo en un bucket de Amazon S3, en lugar de codificar de forma rígida el nombre del bucket, configúrelo como una variable de entorno.

**Evite utilizar invocaciones recursivas** en la función de Lambda, en las que la función se invoca a sí misma o inicia un proceso que puede volver a invocarla. Esto podría producir un volumen no intencionado de invocaciones de la función y costos elevados. Si observa un volumen imprevisto de invocaciones, establezca la simultaneidad reservada de funciones en `0` inmediatamente para limitar todas las invocaciones de la función mientras actualiza el código.

**No utilice API no documentadas y no públicas** en el código de la función de Lambda. Para tiempos de ejecución administrados de AWS Lambda, Lambda aplica periódicamente actualizaciones funcionales y de seguridad a las API internas de Lambda. Estas actualizaciones de las API internas pueden ser incompatibles con versiones anteriores, lo que conlleva consecuencias no deseadas, como errores de invocación si su función depende de estas API no públicas. Consulte la [referencia de la API](https://docs.aws.amazon.com/lambda/latest/api/welcome.html) para obtener una lista de las API disponibles públicamente.

**Escriba el código idempotente.** Escribir el código idempotente para las funciones garantiza que los eventos duplicados se gestionen de la misma manera. El código debe validar y gestionar correctamente los eventos duplicados. Para obtener más información, consulte [¿Cómo puedo hacer que mi función de Lambda sea idempotente?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/).
+ **Evite utilizar la caché de DNS de Java.** Las funciones de Lambda ya almacenan en caché las respuestas de DNS. Si utiliza otra caché de DNS, es posible que se agoten los tiempos de espera de conexión.

  La clase `java.util.logging.Logger` puede habilitar indirectamente la caché de DNS de la JVM. Para anular la configuración predeterminada, defina [networkaddress.cache.ttl](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/InetAddress.html#inetaddress-caching-heading) en 0 antes de inicializar `logger`. Ejemplo:

  ```
  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);
  }
  ```
+ **Reduzca el tiempo que tarda Lambda en desempaquetar los paquetes de implementación** escritos en Java colocando los archivos `.jar` de dependencias en un directorio /lib independiente. Esto es más rápido que colocar todo el código de la función en un único archivo jar con un gran número de archivos `.class`. Para obtener instrucciones, consulte [Implementar funciones de Lambda Java con archivos de archivo .zip o JAR](java-package.md).

# Implementar funciones de Lambda Java con archivos de archivo .zip o JAR
<a name="java-package"></a>

El código de la función AWS Lambda se compone de scripts o programas compilados y sus dependencias. Utiliza un *paquete de implementación* para implementar su código de función en Lambda. Lambda admite dos tipos de paquetes de implementación: imágenes de contenedor y archivos .zip. 

Esta página describe cómo crear un archivo.zip o archivo Jar en su paquete de implementación y luego usar el archivo para implementar el código de función a AWS Lambda con el AWS Command Line Interface (AWS CLI).

**importante**  
Java 25 introdujo la compatibilidad con las cachés anticipadas (AOT). Recomendamos encarecidamente no utilizar las cachés AOT cuando implementa las funciones como archivos.zip o JAR, ya que las cachés pueden provocar un comportamiento inesperado cuando Lambda actualice el tiempo de ejecución administrado. Para obtener información adicional, consulte [Cachés anticipadas (AOT) y CDS](java-customization.md#aot-cds-caches).

**Topics**
+ [Requisitos previos](#java-package-prereqs)
+ [Herramientas y bibliotecas](#java-package-libraries)
+ [Compilación de un paquete de implementación con Gradle](#java-package-gradle)
+ [Uso de capas para las dependencias](#java-package-layers)
+ [Compilación de un paquete de implementación con Maven](#java-package-maven)
+ [Carga de un paquete de despliegue con la consola de Lambda](#java-package-console)
+ [Carga de un paquete de despliegue con la AWS CLI](#java-package-cli)
+ [Carga de un paquete de implementación con AWS SAM](#java-package-cloudformation)

## Requisitos previos
<a name="java-package-prereqs"></a>

La AWS CLI es una herramienta de código abierto que lo habilita para interactuar con los servicios de AWS mediante el uso de comandos en el intérprete de comandos de la línea de comandos. Para completar los pasos de esta sección, debe disponer de la [versión 2 de la AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

## Herramientas y bibliotecas
<a name="java-package-libraries"></a>

AWS proporciona las siguientes bibliotecas de funciones de Java. Estas bibliotecas están disponibles en el [repositorio central de 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) (obligatoria): define interfaces de métodos de controlador y el objeto contextual que el entorno de ejecución pasa al controlador. Si define sus propios tipos de entrada, esta es la única biblioteca que necesita.
+ [com.amazonaws:aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-events): tipos de entrada de eventos procedentes de servicios que invocan funciones de Lambda.
+ [com.amazonaws:aws-lambda-java-log4j2](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-log4j2): una biblioteca de appender de Log4j 2 para Apache que puede usar para agregar el ID solicitado en la invocación actual a los [registros de funciones](java-logging.md).
+ [AWS SDK para Java 2.0](https://github.com/aws/aws-sdk-java-v2): el SDK oficial de AWS para el lenguaje de programación Java.

Agregue estas bibliotecas a la definición de la compilación de la siguiente manera:

------
#### [ 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 crear un paquete de implementación, compile el código de función y las dependencias en un único archivo .zip o Java Archive (JAR). En el caso de Gradle, [use el tipo de compilación `Zip`](#java-package-gradle). En el caso de Apache Maven, [use el complemento Maven Shade](#java-package-maven). Cargue el paquete de despliegue a través de la consola de Lambda, la API de Lambda o AWS Serverless Application Model (AWS SAM).

**nota**  
Para que el tamaño del paquete de implementación sea reducido, empaquete las dependencias de la función en capas. Las capas le permiten administrar las dependencias de forma independiente, pueden utilizarlas varias funciones y pueden compartirse con otras cuentas. Para obtener más información, consulte [Administración de las dependencias de Lambda con capas](chapter-layers.md).

## Compilación de un paquete de implementación con Gradle
<a name="java-package-gradle"></a>

Utilice el tipo de compilación `Zip` para crear un paquete de despliegue con el código de función y las dependencias de Gradle. Este es un ejemplo de un [archivo build.gradle de muestra completo](https://github.com/awsdocs/aws-lambda-developer-guide/blob/main/sample-apps/s3-java/build.gradle):

**Example build.gradle: tarea de compilación**  

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

Esta configuración de compilación produce un paquete de implementación en el directorio `build/distributions`. Dentro de la instrucción `into('lib')`, la tarea `jar` crea un archivo JAR que contiene las clases principales en una carpeta denominada `lib`. A continuación, la tarea `configurations.runtimeClassPath` copia las bibliotecas de dependencias de la ruta de clases de la compilación en el mismo archivo `lib`.

**Example build.gradle: dependencias**  

```
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'
    ...
}
```

Lambda carga los archivos JAR en orden alfabético Unicode. Si hay varios archivos JAR en el directorio `lib` que contienen la misma clase, se utiliza el primero. Puede utilizar el siguiente script de shell para identificar las clases 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
```

## Uso de capas para las dependencias
<a name="java-package-layers"></a>

Se pueden utilizar capas para empaquetar las dependencias de su función de forma independiente y mantener el paquete de implementación reducido. Para obtener más información, consulte [Uso de capas para funciones de Lambda en Java](java-layers.md).

## Compilación de un paquete de implementación con Maven
<a name="java-package-maven"></a>

Para crear un paquete de implementación con Maven, use el [complemento Maven Shade](https://maven.apache.org/plugins/maven-shade-plugin/). El complemento crea un archivo JAR que contiene el código compilado de la función y todas sus dependencias.

**Example pom.xml: configuración del complemento**  

```
      <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 crear el paquete de implementación, utilice el 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] ------------------------------------------------------------------------
```

Este comando genera un archivo JAR en el directorio `target`.

**nota**  
Si trabaja con un [JAR de varias versiones (MRJAR)](https://openjdk.org/jeps/238), debe incluir el MRJAR (es decir, el JAR sombreado producido por el complemento Maven Shade) en el directorio `lib` y comprimirlo antes de subir el paquete de despliegue a Lambda. De lo contrario, es posible que Lambda no descomprima correctamente el archivo JAR, lo que hará que se ignore el archivo `MANIFEST.MF`.

Si utiliza la biblioteca de appender (`aws-lambda-java-log4j2`), también debe configurar un transformador para el complemento Maven Shade. La biblioteca de transformadores combina versiones de un archivo de caché que aparecen tanto en la biblioteca de appender como en Log4j.

**Example pom.xml: configuración del complemento con el appender 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>
```

## Carga de un paquete de despliegue con la consola de Lambda
<a name="java-package-console"></a>

 Para crear una nueva función, primero debe crearla en la consola y, a continuación, cargar el archivo .zip o JAR. Para actualizar una función existente, abra la página de la función y, a continuación, siga el mismo procedimiento para agregar el archivo .zip o JAR actualizado. 

 Si el archivo del paquete de despliegue tiene un tamaño inferior a los 50 MB, puede cargarlo directamente desde su equipo local. Para los archivos .zip o JAR de un tamaño mayor que 50 MB, es preciso cargar el paquete en un bucket de Amazon S3. Para obtener instrucciones sobre cómo cargar un archivo en un bucket de Amazon S3 con la Consola de administración de AWS, consulte [Introducción a Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html). Para cargar archivos mediante la AWS CLI, consulte [Mover objetos](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move) en la *Guía del usuario de la AWS CLI*. 

**nota**  
No puede cambiar el [tipo de paquete de implementación](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-PackageType) (.zip o imagen de contenedor) de una función existente. Por ejemplo, no se puede convertir una función de imagen de contenedor para utilizar un archivo .zip. Debe crear una nueva función.

**Para crear una nueva función (consola)**

1. Abra la [página Funciones](https://console.aws.amazon.com/lambda/home#/functions) de la consola de Lambda y elija **Crear función**.

1. Elija **Crear desde cero**.

1. En **Información básica**, haga lo siguiente:

   1. En **Nombre de la función**, escriba el nombre de la función.

   1. En **Tiempo de ejecución**, seleccione el tiempo de ejecución que desea utilizar.

   1. (Opcional) Para **Arquitectura**, elija la arquitectura del conjunto de instrucciones para su función. La arquitectura predeterminada es x86\$164. Asegúrese de que el paquete de despliegue .zip para su función sea compatible con la arquitectura del conjunto de instrucciones que seleccione.

1. (Opcional) En **Permisos**, expanda **Cambiar función de ejecución predeterminada**. Puede crear un nuevo **Rol de ejecución** o utilizar uno existente.

1. Seleccione **Creación de función**. Lambda crea una función básica “Hola, mundo” mediante el tiempo de ejecución elegido.

**Para cargar un archivo .zip o JAR desde su equipo local (consola)**

1. En la [página Funciones](https://console.aws.amazon.com/lambda/home#/functions) de la consola de Lambda, elija la función para la que desea cargar el archivo .zip o JAR.

1. Seleccione la pestaña **Código**.

1. En el panel **Código fuente**, elija **Cargar desde**.

1. Elija **archivo .zip o .jar**.

1. Para cargar un archivo .zip o JAR, haga lo siguiente:

   1. Seleccione **Cargar** y, a continuación, seleccione su archivo .zip o JAR en el selector de archivos.

   1. Elija **Abrir**.

   1. Seleccione **Save**.

**Para cargar un archivo .zip o JAR desde un bucket de Amazon S3 (consola)**

1. En la [página Funciones](https://console.aws.amazon.com/lambda/home#/functions) de la consola de Lambda, elija la función para la que desea cargar un nuevo archivo .zip o JAR.

1. Seleccione la pestaña **Código**.

1. En el panel **Código fuente**, elija **Cargar desde**.

1. Elija la **ubicación de Amazon S3**.

1. Pegue la URL del enlace de Amazon S3 de su archivo .zip y seleccione **Guardar**.

## Carga de un paquete de despliegue con la AWS CLI
<a name="java-package-cli"></a>

 Puede utilizar la [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para crear una nueva función o actualizar una existente mediante un archivo .zip o JAR. Utilice los comandos [create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) y [update-function-code](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) para implementar el paquete .zip o JAR. Si el archivo tiene un tamaño inferior a los 50 MB, puede cargarlo desde su equipo de compilación local. Para archivos más grandes, es preciso cargar el paquete .zip o JAR desde un bucket de Amazon S3. Para obtener instrucciones sobre cómo cargar un archivo en un bucket de Amazon S3 con la AWS CLI, consulte [Mover objetos](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move) en la *Guía del usuario de la AWS CLI*. 

**nota**  
Si carga su archivo .zip o JAR desde un bucket de Amazon S3 con la AWS CLI, el bucket debe estar ubicado en la misma Región de AWS que su función.

 Para crear una nueva función mediante un archivo .zip o JAR con la AWS CLI, debe especificar lo siguiente: 
+ El nombre de la función (`--function-name`).
+ El tiempo de ejecución de la función (`--runtime`).
+ El nombre de recurso de Amazon (ARN) del [rol de ejecución](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html) de la función (`--role`).
+ El nombre del método de controlador en el código de la función (`--handler`).

 También debe especificar la ubicación del archivo .zip o JAR. Si el archivo .zip o JAR se encuentra en una carpeta de su equipo de compilación local, utilice la opción `--zip-file` para especificar la ruta del archivo, tal como se muestra en el siguiente comando de ejemplo. 

```
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 la ubicación del archivo .zip en un bucket de Amazon S3, utilice la opción `--code`, como se muestra en el siguiente comando de ejemplo. Solo necesita utilizar el parámetro `S3ObjectVersion` para los objetos con versiones. 

```
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 actualizar una función existente mediante la CLI, especifique el nombre de la función mediante el parámetro `--function-name`. También debe especificar la ubicación del archivo .zip que desea utilizar para actualizar el código de la función. Si el archivo .zip se encuentra en una carpeta de su equipo de compilación local, utilice la opción `--zip-file` para especificar la ruta del archivo, como se muestra en el siguiente comando de ejemplo. 

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

 Para especificar la ubicación del archivo .zip en un bucket de Amazon S3, utilice las opciones `--s3-bucket` y `--s3-key` tal como se muestra en el siguiente comando de ejemplo. Solo necesita usar el parámetro `--s3-object-version` para los objetos con versiones. 

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

## Carga de un paquete de implementación con AWS SAM
<a name="java-package-cloudformation"></a>

Puede usar el AWS SAM para automatizar las implementaciones del código de función, la configuración y las dependencias. AWS SAM es una extensión de CloudFormation que proporciona una sintaxis simplificada para definir aplicaciones sin servidor. En la siguiente plantilla de ejemplo, se define una función con un paquete de implementación en el directorio `build/distributions` que usa Gradle:

**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 crear la función, utilice los comandos `package` y `deploy`. Estos comandos son personalizaciones de la CLI de AWS CLI. Contienen otros comandos que van a cargar el paquete de implementación en Amazon S3, reescribir la plantilla con el URI del objeto y actualizar el código de la función.

El siguiente script de ejemplo ejecuta una compilación de Gradle y carga el paquete de implementación que crea. Crea una pila de CloudFormation la primera vez que la ejecuta. Si la pila ya existe, el script la actualiza.

**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 ver un ejemplo completo, consulte las siguientes aplicaciones:

**Aplicaciones de Lambda de ejemplo en Java**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java): función de Java que demuestra cómo se puede utilizar Lambda para procesar pedidos. Esta función muestra cómo definir y deserializar un objeto de evento de entrada personalizado, cómo usar el SDK de AWS y cómo registrar los resultados.
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic): una colección de funciones de Java mínimas con pruebas unitarias y configuración de registro variable.
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events): una colección de funciones Java que contiene un código básico sobre cómo gestionar los eventos de varios servicios, como Amazon API Gateway, Amazon SQS y Amazon Kinesis. Estas funciones utilizan la última versión de la biblioteca [aws-lambda-java-events](#java-package) (3.0.0 y más recientes). Estos ejemplos no requieren utilizar AWS SDK como una dependencia.
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java): una función de Java que procesa los eventos de notificación de Amazon S3 y utiliza Java Class Library (JCL) para crear miniaturas de los archivos de imagen cargados.
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java): función de Java que ilustra cómo utilizar una capa de Lambda para empaquetar las dependencias de forma separada del código de la función principal.

# Implementar funciones Java Lambda con imágenes de contenedor
<a name="java-image"></a>

Hay tres formas de crear una imagen de contenedor para una función de Lambda en Java:
+ [Uso de una imagen base de AWS para Java](#java-image-instructions)

  Las [imágenes base de AWS](images-create.md#runtimes-images-lp) vienen precargadas con un tiempo de ejecución de lenguaje, un cliente de interfaz de tiempo de ejecución para administrar la interacción entre Lambda y el código de la función y un emulador de interfaz de tiempo de ejecución para realizar pruebas a nivel local.
+ [Uso de una imagen base exclusiva del sistema operativo de AWS](images-create.md#runtimes-images-provided)

  [Las imágenes base exclusivas del sistema operativo de AWS](https://gallery.ecr.aws/lambda/provided)contienen una distribución de Amazon Linux y el [emulador de interfaz de tiempo de ejecución](https://github.com/aws/aws-lambda-runtime-interface-emulator/). Por lo general, estas imágenes se utilizan para crear imágenes contenedoras para lenguajes compilados, como [Go](go-image.md#go-image-provided) y [Rust](lambda-rust.md), y para un lenguaje o versión de un lenguaje para los que Lambda no proporciona una imagen base, como Node.js 19. También puede usar imágenes base exclusivas del sistema operativo para implementar un [tiempo de ejecución personalizado](runtimes-custom.md). Para que la imagen sea compatible con Lambda, debe incluir el [cliente de interfaz de tiempo de ejecución para Java](#java-image-clients) en la imagen.
+ [Uso de una imagen base que no sea de AWS](#java-image-clients)

  Puede utilizar una imagen base alternativa de otro registro de contenedores, como Alpine Linux o Debian. También puede utilizar una imagen personalizada creada por su organización. Para que la imagen sea compatible con Lambda, debe incluir el [cliente de interfaz de tiempo de ejecución para Java](#java-image-clients) en la imagen.

**sugerencia**  
Para reducir el tiempo que tardan las funciones de contenedor de Lambda en activarse, consulte [Uso de compilaciones de varias fases](https://docs.docker.com/build/building/multi-stage/) en la documentación de Docker. Para compilar imágenes de contenedores eficientes, siga [Prácticas recomendadas para escribir Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).

En esta página, se explica cómo compilar, probar e implementar imágenes de contenedor para Lambda.

**Topics**
+ [AWSImágenes base de para Java](#java-image-base)
+ [Uso de una imagen base de AWS para Java](#java-image-instructions)
+ [Uso de una imagen base alternativa con el cliente de interfaz de tiempo de ejecución](#java-image-clients)

## AWSImágenes base de para Java
<a name="java-image-base"></a>

AWS proporciona las siguientes imágenes base para Java:


| Etiquetas | Tiempo de ejecución | Sistema operativo | Dockerfile | Obsolescencia | 
| --- | --- | --- | --- | --- | 
| 25 | Java 25 | Amazon Linux 2023 | [Dockerfile para Java 25 en GitHub](https://github.com/aws/aws-lambda-base-images/blob/java25/Dockerfile.java25) |   30 de junio de 2029   | 
| 21 | Java 21 | Amazon Linux 2023 | [Dockerfile para Java 21 en GitHub](https://github.com/aws/aws-lambda-base-images/blob/java21/Dockerfile.java21) |   30 de junio de 2029   | 
| 17 | Java 17 | Amazon Linux 2 | [Dockerfile para Java 17 en GitHub](https://github.com/aws/aws-lambda-base-images/blob/java17/Dockerfile.java17) |   30 de junio de 2027   | 
| 11 | Java 11 | Amazon Linux 2 | [Dockerfile para Java 11 en GitHub](https://github.com/aws/aws-lambda-base-images/blob/java11/Dockerfile.java11) |   30 de junio de 2027   | 
| 8.al2 | Java 8 | Amazon Linux 2 | [Dockerfile para Java 8 en GitHub](https://github.com/aws/aws-lambda-base-images/blob/java8.al2/Dockerfile.java8.al2) |   30 de junio de 2027   | 

Repositorio de Amazon ECR: [gallery.ecr.aws/lambda/java](https://gallery.ecr.aws/lambda/java)

Las imágenes base de Java 21 y versiones posteriores se basan en la [imagen de contenedor mínima de Amazon Linux 2023](https://docs.aws.amazon.com/linux/al2023/ug/minimal-container.html). Las imágenes base anteriores utilizan Amazon Linux 2. AL2023 ofrece varias ventajas con respecto a Amazon Linux 2, incluida una huella de implementación más reducida y versiones actualizadas de bibliotecas como `glibc`.

Las imágenes basadas en AL2023 utilizan `microdnf` (enlazadas simbólicamente como `dnf`) como administrador de paquetes en lugar de `yum`, que es el administrador de paquetes predeterminado en Amazon Linux 2. `microdnf` es una implementación independiente de `dnf`. Para obtener una lista de los paquetes que se incluyen en las imágenes basadas en AL2023, consulte las columnas de **Minimal Container** de [Comparing packages installed on Amazon Linux 2023 Container Images](https://docs.aws.amazon.com/linux/al2023/ug/al2023-container-image-types.html). Para obtener más información sobre las diferencias entre AL2023 y Amazon Linux 2, consulte [Introducing the Amazon Linux 2023 runtime for AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-amazon-linux-2023-runtime-for-aws-lambda/) en el Blog de informática de AWS.

**nota**  
Para ejecutar imágenes basadas en AL2023 de forma local, incluso con AWS Serverless Application Model (AWS SAM), debe usar Docker en la versión 20.10.10 o posterior.

## Uso de una imagen base de AWS para Java
<a name="java-image-instructions"></a>

### Requisitos previos
<a name="java-image-prerequisites"></a>

Para completar los pasos de esta sección, debe disponer de lo siguiente:
+ Java (por ejemplo, [Amazon Corretto](https://aws.amazon.com/corretto))
+ [Apache Maven](https://maven.apache.org/) o [Gradle](https://gradle.org/install/)
+ [AWS CLI versión 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (versión mínima 25.0.0)
+ El [complemento buildx](https://github.com/docker/buildx/blob/master/README.md) de Docker.

### Creación de una imagen a partir de una imagen base
<a name="java-image-create"></a>

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

1. Ejecute el siguiente comando para crear un proyecto de Maven con el [arquetipo de Lambda](https://github.com/aws/aws-sdk-java-v2/tree/master/archetypes/archetype-lambda). Se requieren los siguientes parámetros:
   + **service**: el cliente del Servicio de AWS que se va a utilizar en la función de Lambda. Para ver una lista de las fuentes disponibles, consulte [aws-sdk-java-v2/services](https://github.com/aws/aws-sdk-java-v2/tree/master/services) en GitHub.
   + **region**: la Región de AWS en la que desea crear la función de Lambda.
   + **groupId**: el espacio de nombres completo del paquete de la aplicación.
   + **artifactId**: el nombre del proyecto. Esto se convierte en el nombre del directorio del proyecto.

   En Linux y macOS, ejecute 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
   ```

   En PowerShell, ejecute 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"
   ```

   El arquetipo de Maven para Lambda está preconfigurado para compilar con Java SE 8 e incluye una dependencia a AWS SDK para Java. Si crea su proyecto con un arquetipo diferente o mediante otro método, debe [configurar el compilador de Java para Maven](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#configure-maven-compiler) y [declarar el SDK como dependencia](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#configure-maven-compiler).

1. Abra el directorio `myapp/src/main/java/com/example/myapp` y busque el archivo `App.java`. Se trata del código de la función de Lambda. Puede utilizar el código de muestra proporcionado para realizar pruebas o sustituirlo por su propio código.

1. Regrese al directorio raíz del proyecto y, a continuación, cree un nuevo Dockerfile con la siguiente configuración:
   + Establezca la propiedad `FROM` en el [URI de la imagen base](https://gallery.ecr.aws/lambda/java).
   + Establezca el argumento `CMD` para el controlador de la función de Lambda.

   Tenga en cuenta que el Dockerfile de ejemplo no incluye una [instrucción USER](https://docs.docker.com/reference/dockerfile/#user). Al implementar una imagen de contenedor en Lambda, Lambda define automáticamente un usuario predeterminado de Linux con permisos de privilegio mínimo. Esto es diferente del comportamiento estándar de Docker, que utiliza de forma predeterminada el usuario `root` cuando no se proporciona ninguna instrucción `USER`.  
**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 el proyecto y recopile las dependencias del tiempo de ejecución.

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

1. Cree la imagen de Docker con el comando [docker build](https://docs.docker.com/engine/reference/commandline/build/). En el siguiente ejemplo se asigna un nombre a la imagen `docker-image` y se le asigna la [etiqueta](https://docs.docker.com/engine/reference/commandline/build/#tag) `test`. Para que la imagen sea compatible con Lambda, debe usar la opción `--provenance=false`.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**nota**  
El comando especifica la opción `--platform linux/amd64` para garantizar que el contenedor sea compatible con el entorno de ejecución de Lambda, independientemente de la arquitectura de la máquina de compilación. Si tiene intención de crear una función de Lambda con la arquitectura del conjunto de instrucciones ARM64, asegúrese de cambiar el comando para utilizar la opción `--platform linux/arm64` en su lugar.

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

1. Cree un directorio para el proyecto y, a continuación, cambie a ese directorio.

   ```
   mkdir example
   cd example
   ```

1. Ejecute el siguiente comando para que Gradle genere un nuevo proyecto de aplicación Java en el directorio `example` de su entorno. En **Seleccionar DSL del script de compilación**, elija **2:** Groovy.

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

1. Abra el directorio `/example/app/src/main/java/example` y busque el archivo `App.java`. Se trata del código de la función de Lambda. Puede utilizar el siguiente código de muestra para realizar pruebas o sustituirlo por su propio 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 el archivo `build.gradle`. Si utiliza el código de función de muestra del paso anterior, sustituya el contenido de `build.gradle` por lo siguiente. Si utiliza su propio código de función, modifique el archivo `build.gradle` según sea necesario.  
**Example build.gradle (Groovy DSL)**  

   ```
   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. El comando `gradle init` del paso 2 también generó un caso de prueba ficticio en el directorio `app/test`. Para los fines de este tutorial, evite la ejecución de las pruebas al eliminar el directorio de `/test`.

1. Compilar el proyecto.

   ```
   gradle build
   ```

1. En el directorio raíz del proyecto (`/example`), cree un Dockerfile con la siguiente configuración:
   + Establezca la propiedad `FROM` en el [URI de la imagen base](https://gallery.ecr.aws/lambda/java).
   + Utilice el comando COPY para copiar el código de la función y las dependencias del tiempo de ejecución a `{LAMBDA_TASK_ROOT}`, una [variable de entorno definido de Lambda](configuration-envvars.md#configuration-envvars-runtime).
   + Establezca el argumento `CMD` para el controlador de la función de Lambda.

   Tenga en cuenta que el Dockerfile de ejemplo no incluye una [instrucción USER](https://docs.docker.com/reference/dockerfile/#user). Al implementar una imagen de contenedor en Lambda, Lambda define automáticamente un usuario predeterminado de Linux con permisos de privilegio mínimo. Esto es diferente del comportamiento estándar de Docker, que utiliza de forma predeterminada el usuario `root` cuando no se proporciona ninguna instrucción `USER`.  
**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. Cree la imagen de Docker con el comando [docker build](https://docs.docker.com/engine/reference/commandline/build/). En el siguiente ejemplo se asigna un nombre a la imagen `docker-image` y se le asigna la [etiqueta](https://docs.docker.com/engine/reference/commandline/build/#tag) `test`. Para que la imagen sea compatible con Lambda, debe usar la opción `--provenance=false`.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**nota**  
El comando especifica la opción `--platform linux/amd64` para garantizar que el contenedor sea compatible con el entorno de ejecución de Lambda, independientemente de la arquitectura de la máquina de compilación. Si tiene intención de crear una función de Lambda con la arquitectura del conjunto de instrucciones ARM64, asegúrese de cambiar el comando para utilizar la opción `--platform linux/arm64` en su lugar.

------

### (Opcional) Prueba de la imagen de forma local
<a name="java-image-test"></a>

1. Inicie la imagen de Docker con el comando **docker run**. En este ejemplo, `docker-image` es el nombre de la imagen y `test` es la etiqueta.

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

   Este comando ejecuta la imagen como un contenedor y crea un punto de conexión local en `localhost:9000/2015-03-31/functions/function/invocations`.
**nota**  
Si creó la imagen de Docker para la arquitectura del conjunto de instrucciones ARM64, asegúrese de utilizar la opción `--platform linux/arm64` en lugar de `--platform linux/amd64`.

1. Desde una nueva ventana de terminal, publique un evento en el punto de conexión local.

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

   En Linux y macOS, ejecute el siguiente comando `curl`:

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

   Este comando invoca la función con un evento vacío y devuelve una respuesta. Si utiliza su propio código de función en lugar del código de función de ejemplo, quizás quiera invocar la función con una carga JSON. Ejemplo:

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

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

   En PowerShell, ejecute el siguiente comando `Invoke-WebRequest`:

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

   Este comando invoca la función con un evento vacío y devuelve una respuesta. Si utiliza su propio código de función en lugar del código de función de ejemplo, quizás quiera invocar la función con una carga JSON. Ejemplo:

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

------

1. Obtenga el ID del contenedor.

   ```
   docker ps
   ```

1. Use el comando [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) para detener el contenedor. En este comando, reemplace `3766c4ab331c` por el ID del contenedor del paso anterior.

   ```
   docker kill 3766c4ab331c
   ```

### Implementación de la imagen
<a name="java-image-deploy"></a>

**Para cargar la imagen en Amazon ECR y crear la función de Lambda**

1. Para autenticar la CLI de Docker en su registro de Amazon ECR, ejecute el comando [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html).
   + Establezca el valor de `--region` en la Región de AWS en la que desee crear el repositorio de Amazon ECR.
   + Reemplace `111122223333` por el ID de su Cuenta de 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. Cree un repositorio en Amazon ECR con el 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**  
El repositorio de Amazon ECR debe estar en la misma Región de AWS que la función de Lambda.

   Si se realiza de la forma correcta, verá una respuesta como la siguiente:

   ```
   {
       "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 el valor de `repositoryUri` de la salida del paso anterior.

1. Ejecute el comando [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) para etiquetar la imagen local en su repositorio de Amazon ECR como la versión más reciente. En este comando:
   + `docker-image:test` es el nombre y la [etiqueta](https://docs.docker.com/engine/reference/commandline/build/#tag) de su imagen de Docker. Son el nombre y la etiqueta de la imagen que especificó en el comando `docker build`.
   + Reemplace `<ECRrepositoryUri>` por el `repositoryUri` que ha copiado. Asegúrese de incluir `:latest` al final del URI.

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

   Ejemplo:

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

1. Ejecute el comando [docker push](https://docs.docker.com/engine/reference/commandline/push/) para implementar la imagen local en el repositorio de Amazon ECR. Asegúrese de incluir `:latest` al final del URI del repositorio.

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

1. [Cree un rol de ejecución](lambda-intro-execution-role.md#permissions-executionrole-api) para la función si aún no tiene uno. Necesitará el nombre de recurso de Amazon (ARN) del rol en el paso siguiente.

1. Cree la función de Lambda. En `ImageUri`, especifique el URI del repositorio anterior. Asegúrese de incluir `:latest` al final del 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**  
Puede crear una función con una imagen de una cuenta AWS diferente, siempre que la imagen esté en la misma región que la función de Lambda. Para obtener más información, consulte [Permisos entre cuentas de Amazon ECR](images-create.md#configuration-images-xaccount-permissions).

1. Invoque la función.

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

   Debería ver una respuesta como la siguiente:

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

1. Para ver la salida de la función, compruebe el archivo `response.json`.

Para actualizar el código de la función, debe volver a compilar la imagen, cargar la nueva imagen en el repositorio de Amazon ECR y, a continuación, utilizar el comando [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) para implementar la imagen en la función de Lambda.

Lambda resuelve la etiqueta de la imagen en un resumen de imagen específico. Esto significa que si apunta la etiqueta de imagen que se utilizó para implementar la función a una nueva imagen en Amazon ECR, Lambda no actualiza automáticamente la función para usar la nueva imagen.

Para implementar la nueva imagen en la misma función de Lambda, debe usar el comando [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html), incluso si la etiqueta de la imagen en Amazon ECR sigue siendo la misma. En el siguiente ejemplo, la opción `--publish` crea una nueva versión de la función con la imagen del contenedor actualizada.

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

## Uso de una imagen base alternativa con el cliente de interfaz de tiempo de ejecución
<a name="java-image-clients"></a>

Si usa una [imagen base exclusiva del sistema operativo](images-create.md#runtimes-images-provided) o una imagen base alternativa, debe incluir el cliente de interfaz de tiempo de ejecución en su imagen. El cliente de interfaz de tiempo de ejecución extiende el [API de tiempo de ejecución](runtimes-api.md), que administra la interacción entre Lambda y el código de la función.

Instale el cliente de interfaz de tiempo de ejecución para Java en su Dockerfile o como una dependencia en su proyecto. Por ejemplo, para instalar el cliente de interfaz de tiempo de ejecución mediante el administrador de paquetes de Maven, agregue los siguientes a su archivo `pom.xml`:

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

Para obtener detalles sobre el paquete, consulte [AWS Lambda Java Runtime Interface Client](https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-runtime-interface-client) en Maven Central Repository. También puede ver el código fuente del cliente de interfaz de tiempo de ejecución de Java en el repositorio de GitHub [AWS Lambda Java Support Libraries](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-runtime-interface-client).

En el siguiente ejemplo, se muestra cómo crear una imagen de contenedor para Java mediante una [imagen de Amazon Corretto](https://gallery.ecr.aws/amazoncorretto/amazoncorretto). Amazon Corretto es una distribución sin costo, multiplataforma y lista para producción de Open Java Development Kit (OpenJDK). El proyecto Maven incluye el cliente de interfaz de tiempo de ejecución como una dependencia.

### Requisitos previos
<a name="java-alt-prerequisites"></a>

Para completar los pasos de esta sección, debe disponer de lo siguiente:
+ Java (por ejemplo, [Amazon Corretto](https://aws.amazon.com/corretto))
+ [Apache Maven](https://maven.apache.org/)
+ [AWS CLI versión 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (versión mínima 25.0.0)
+ El [complemento buildx](https://github.com/docker/buildx/blob/master/README.md) de Docker.

### Creación de imágenes a partir de una imagen base alternativa
<a name="java-alt-create"></a>

1. Cree un proyecto de Maven. Se requieren los siguientes parámetros:
   + **groupId**: el espacio de nombres completo del paquete de la aplicación.
   + **artifactId**: el nombre del proyecto. Esto se convierte en el nombre del directorio del proyecto.

------
#### [ 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 el directorio del proyecto.

   ```
   cd myapp
   ```

1. Reemplace el contenido del archivo `pom.xml` por lo siguiente. Este archivo contiene el [aws-lambda-java-runtime-interface-client](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-runtime-interface-client) como dependencia. Como opción, puede instalar el cliente de interfaz de tiempo de ejecución en el Dockerfile. Sin embargo, el enfoque más simple es incluir la biblioteca como una dependencia.

   ```
   <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 el directorio `myapp/src/main/java/com/example/myapp` y busque el archivo `App.java`. Se trata del código de la función de Lambda. Reemplace el código con lo siguiente.  
**Example controlador de funciones**  

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

1. El comando `mvn -B archetype:generate` del paso 1 también generó un caso de prueba ficticio en el directorio `src/test`. Para los fines de este tutorial, evite la ejecución de las pruebas y elimine todo este directorio de `/test` generado.

1. Regrese al directorio raíz del proyecto y, a continuación, crea un nuevo Dockerfile. El siguiente Dockerfile de ejemplo usa una [imagen de Amazon Corretto](https://gallery.ecr.aws/amazoncorretto/amazoncorretto). Amazon Corretto es una distribución sin costo, multiplataforma y lista para producción de OpenJDK.
   + Establezca la propiedad `FROM` en el URI de la imagen base.
   + Configure `ENTRYPOINT` como el módulo que desea que el contenedor de Docker ejecute cuando se inicie. En este caso, el módulo es el cliente de interfaz de tiempo de ejecución.
   + Establezca el argumento `CMD` para el controlador de la función de Lambda.

   Tenga en cuenta que el Dockerfile de ejemplo no incluye una [instrucción USER](https://docs.docker.com/reference/dockerfile/#user). Al implementar una imagen de contenedor en Lambda, Lambda define automáticamente un usuario predeterminado de Linux con permisos de privilegio mínimo. Esto es diferente del comportamiento estándar de Docker, que utiliza de forma predeterminada el usuario `root` cuando no se proporciona ninguna instrucción `USER`.  
**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. Cree la imagen de Docker con el comando [docker build](https://docs.docker.com/engine/reference/commandline/build/). En el siguiente ejemplo se asigna un nombre a la imagen `docker-image` y se le asigna la [etiqueta](https://docs.docker.com/engine/reference/commandline/build/#tag) `test`. Para que la imagen sea compatible con Lambda, debe usar la opción `--provenance=false`.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**nota**  
El comando especifica la opción `--platform linux/amd64` para garantizar que el contenedor sea compatible con el entorno de ejecución de Lambda, independientemente de la arquitectura de la máquina de compilación. Si tiene intención de crear una función de Lambda con la arquitectura del conjunto de instrucciones ARM64, asegúrese de cambiar el comando para utilizar la opción `--platform linux/arm64` en su lugar.

### (Opcional) Prueba de la imagen de forma local
<a name="java-alt-test"></a>

Utilice el [emulador de interfaz de tiempo de ejecución](https://github.com/aws/aws-lambda-runtime-interface-emulator/) para probar la imagen localmente. Puede [crear el emulador en su imagen](https://github.com/aws/aws-lambda-runtime-interface-emulator/?tab=readme-ov-file#build-rie-into-your-base-image) o usar el procedimiento siguiente para instalarlo en su equipo local.

**Para instalar y ejecutar el emulador de interfaz de tiempo de ejecución en su equipo local**

1. Desde el directorio del proyecto, ejecute el siguiente comando para descargar el emulador de interfaz de tiempo de ejecución (arquitectura x86-64) de GitHub e instalarlo en su equipo 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 el emulador arm64, reemplace la URL del repositorio de GitHub en el comando anterior por lo siguiente:

   ```
   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 el emulador arm64, reemplace el `$downloadLink` con lo siguiente:

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

------

1. Inicie la imagen de Docker con el comando **docker run**. Tenga en cuenta lo siguiente:
   + `docker-image` es el nombre de la imagen y `test` es la etiqueta.
   + `/usr/bin/java -cp './*' com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App::sayHello` es el `ENTRYPOINT` seguido del `CMD` de su 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
   ```

------

   Este comando ejecuta la imagen como un contenedor y crea un punto de conexión local en `localhost:9000/2015-03-31/functions/function/invocations`.
**nota**  
Si creó la imagen de Docker para la arquitectura del conjunto de instrucciones ARM64, asegúrese de utilizar la opción `--platform linux/arm64` en lugar de `--platform linux/amd64`.

1. Publique un evento en el punto de conexión local.

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

   En Linux y macOS, ejecute el siguiente comando `curl`:

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

   Este comando invoca la función con un evento vacío y devuelve una respuesta. Si utiliza su propio código de función en lugar del código de función de ejemplo, quizás quiera invocar la función con una carga JSON. Ejemplo:

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

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

   En PowerShell, ejecute el siguiente comando `Invoke-WebRequest`:

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

   Este comando invoca la función con un evento vacío y devuelve una respuesta. Si utiliza su propio código de función en lugar del código de función de ejemplo, quizás quiera invocar la función con una carga JSON. Ejemplo:

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

------

1. Obtenga el ID del contenedor.

   ```
   docker ps
   ```

1. Use el comando [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) para detener el contenedor. En este comando, reemplace `3766c4ab331c` por el ID del contenedor del paso anterior.

   ```
   docker kill 3766c4ab331c
   ```

### Implementación de la imagen
<a name="java-alt-deploy"></a>

**Para cargar la imagen en Amazon ECR y crear la función de Lambda**

1. Para autenticar la CLI de Docker en su registro de Amazon ECR, ejecute el comando [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html).
   + Establezca el valor de `--region` en la Región de AWS en la que desee crear el repositorio de Amazon ECR.
   + Reemplace `111122223333` por el ID de su Cuenta de 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. Cree un repositorio en Amazon ECR con el 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**  
El repositorio de Amazon ECR debe estar en la misma Región de AWS que la función de Lambda.

   Si se realiza de la forma correcta, verá una respuesta como la siguiente:

   ```
   {
       "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 el valor de `repositoryUri` de la salida del paso anterior.

1. Ejecute el comando [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) para etiquetar la imagen local en su repositorio de Amazon ECR como la versión más reciente. En este comando:
   + `docker-image:test` es el nombre y la [etiqueta](https://docs.docker.com/engine/reference/commandline/build/#tag) de su imagen de Docker. Son el nombre y la etiqueta de la imagen que especificó en el comando `docker build`.
   + Reemplace `<ECRrepositoryUri>` por el `repositoryUri` que ha copiado. Asegúrese de incluir `:latest` al final del URI.

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

   Ejemplo:

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

1. Ejecute el comando [docker push](https://docs.docker.com/engine/reference/commandline/push/) para implementar la imagen local en el repositorio de Amazon ECR. Asegúrese de incluir `:latest` al final del URI del repositorio.

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

1. [Cree un rol de ejecución](lambda-intro-execution-role.md#permissions-executionrole-api) para la función si aún no tiene uno. Necesitará el nombre de recurso de Amazon (ARN) del rol en el paso siguiente.

1. Cree la función de Lambda. En `ImageUri`, especifique el URI del repositorio anterior. Asegúrese de incluir `:latest` al final del 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**  
Puede crear una función con una imagen de una cuenta AWS diferente, siempre que la imagen esté en la misma región que la función de Lambda. Para obtener más información, consulte [Permisos entre cuentas de Amazon ECR](images-create.md#configuration-images-xaccount-permissions).

1. Invoque la función.

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

   Debería ver una respuesta como la siguiente:

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

1. Para ver la salida de la función, compruebe el archivo `response.json`.

Para actualizar el código de la función, debe volver a compilar la imagen, cargar la nueva imagen en el repositorio de Amazon ECR y, a continuación, utilizar el comando [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) para implementar la imagen en la función de Lambda.

Lambda resuelve la etiqueta de la imagen en un resumen de imagen específico. Esto significa que si apunta la etiqueta de imagen que se utilizó para implementar la función a una nueva imagen en Amazon ECR, Lambda no actualiza automáticamente la función para usar la nueva imagen.

Para implementar la nueva imagen en la misma función de Lambda, debe usar el comando [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html), incluso si la etiqueta de la imagen en Amazon ECR sigue siendo la misma. En el siguiente ejemplo, la opción `--publish` crea una nueva versión de la función con la imagen del contenedor actualizada.

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

# Uso de capas para funciones de Lambda en Java
<a name="java-layers"></a>

Utilice [capas de Lambda](chapter-layers.md) para empaquetar el código y las dependencias que desee reutilizar en varias funciones. Las capas suelen contener dependencias de biblioteca, un [tiempo de ejecución personalizado](runtimes-custom.md) o archivos de configuración. La creación de una capa implica tres pasos generales:

1. Empaquete el contenido de su capa. Esto significa crear un archivo de archivo. zip que contenga las dependencias que desea usar en sus funciones.

1. Cree la capa en Lambda.

1. Agregue la capa a sus funciones.

**Topics**
+ [Empaquete el contenido de su capa.](#java-layers-package)
+ [Creación de la capa en Lambda](#publishing-layer)
+ [Adición de la capa a la función](#java-layer-adding)

## Empaquete el contenido de su capa.
<a name="java-layers-package"></a>

Para crear una capa, agrupe sus paquetes en un archivo .zip que cumpla con los siguientes requisitos:
+ Asegúrese de que la versión de Java a la que hace referencia Maven o Gradle sea la misma que la versión de Java de la función que se pretende implementar. Por ejemplo, para una función de Java 25, el comando `mvn -v` debería incluir Java 25 en el resultado:
+ Las dependencias deben estar almacenadas en el directorio `java/lib`, en la raíz del archivo .zip. Para obtener más información, consulte [Rutas de capa para cada tiempo de ejecución de Lambda](packaging-layers.md#packaging-layers-paths).
+ Los paquetes de la capa deben ser compatibles con Linux. Las funciones de Lambda se ejecutan en Amazon Linux.

Puede crear capas que contengan bibliotecas de Java de terceros o sus propios módulos y paquetes de Java. El siguiente procedimiento utiliza Maven. También puede usar Gradle para empaquetar el contenido de la capa.

**Crear una capa mediante las dependencias de Maven**

1. Cree un proyecto de Apache Maven con un archivo `pom.xml` que defina las dependencias.

   El siguiente ejemplo incluye [Jackson Databind](https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind) para el procesamiento de JSON. La sección `<build>` usa el complemento [maven-dependency-plugin](https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-dependency-plugin) para crear archivos JAR independientes para cada dependencia en lugar de agruparlos en un único uber-jar. Si quiere crear un 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. Compilar el proyecto. Este comando crea todos los archivos JAR de dependencia en el directorio `target/lib/`.

   ```
   mvn clean package
   ```

1. Cree la estructura del directorio necesario para su capa:

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

1. Copie los archivos JAR de dependencia en el directorio `java/lib`:

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

1. Comprima en formato zip el contenido de la capa:

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

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

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

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

------

   La estructura de directorios del archivo .zip debería ser similar a la siguiente:

   ```
   java/              
   └── lib/
       ├── jackson-databind-2.17.0.jar
       ├── jackson-core-2.17.0.jar
       └── jackson-annotations-2.17.0.jar
   ```
**nota**  
Asegúrese de que su archivo .zip incluya el directorio `java` en el nivel raíz con `lib` en su interior. Esta estructura garantiza que Lambda pueda localizar e importar sus bibliotecas. Cada dependencia se mantiene como un archivo JAR independiente en lugar de estar agrupadas en un uber-jar.

## Creación de la capa en Lambda
<a name="publishing-layer"></a>

También puede publicar la capa con la AWS CLI o la consola de Lambda.

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

Ejecute el comando [publish-layer-version](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/publish-layer-version.html) de la AWS CLI para crear la capa de Lambda:

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

El parámetro [Tiempos de ejecución compatibles](https://docs.aws.amazon.com/lambda/latest/api/API_PublishLayerVersion.html#lambda-PublishLayerVersion-request-CompatibleRuntimes) es opcional. Cuando se especifica, Lambda usa este parámetro para filtrar las capas en la consola de Lambda.

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

**Para crear una capa (consola)**

1. Abra la página de [Capas](https://console.aws.amazon.com/lambda/home#/layers) de la consola de Lambda.

1. Elija **Crear capa**.

1. Elija **Cargar un archivo .zip** y, a continuación, cargue el archivo .zip que creó anteriormente.

1. (Opcional) En **Tiempos de ejecución compatibles**, elija el tiempo de ejecución de Java que corresponda a la versión de Java que utilizó para crear la capa.

1. Seleccione **Crear**.

------

## Adición de la capa a la función
<a name="java-layer-adding"></a>

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

Para adjuntar la capa a la función, ejecute el comando [update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) de la AWS CLI. Para el parámetro `--layers`, use el ARN de la capa. El ARN debe especificar la versión (por ejemplo, `arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1`). Para obtener más información, consulte [Capas y versiones de capas](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"
```

La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 2*.

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

**Adición de una capa a una función**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija la función.

1. Desplácese hacia abajo hasta la sección **Capas** y, a continuación, elija **Agregar una capa**.

1. En **Elija una capa**, seleccione **Capas personalizadas** y, a continuación, elija su capa.
**nota**  
Si no agregó un [tiempo de ejecución compatible](https://docs.aws.amazon.com/lambda/latest/api/API_PublishLayerVersion.html#lambda-PublishLayerVersion-request-CompatibleRuntimes) al crear la capa, su capa no aparecerá aquí. Puede especificar el ARN de la capa en su lugar.

1. Seleccione **Añadir**.

------

# Personalización de la serialización para las funciones Java de Lambda
<a name="java-custom-serialization"></a>

Los [tiempos de ejecución administrados por Java](lambda-java.md#java-runtimes) de Lambda admiten la serialización personalizada para eventos JSON. La serialización personalizada puede simplificar el código y, potencialmente, mejorar el rendimiento.

**Topics**
+ [Cuándo se usa la serialización personalizada](#custom-serialization-use-cases)
+ [Implementación de una serialización personalizada](#implement-custom-serialization)
+ [Prueba de la serialización personalizada](#test-custom-serialization)

## Cuándo se usa la serialización personalizada
<a name="custom-serialization-use-cases"></a>

Cuando se invoca la función de Lambda, los datos del evento de entrada deben deserializarse en un objeto de Java y la salida de la función debe volver a serializarse en un formato que pueda devolverse como respuesta de la función. Los tiempos de ejecución administrados por Java de Lambda proporcionan capacidades de serialización y deserialización predeterminadas que funcionan bien para gestionar las cargas útiles de eventos de varios servicios de AWS, como Amazon API Gateway y Amazon Simple Queue Service (Amazon SQS). Para trabajar con estos eventos de integración de servicios en la función, agregue la dependencia [aws-java-lambda-events](https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-events) a su proyecto. Esta biblioteca de AWS contiene objetos de Java que representan estos eventos de integración de servicios.

También puede usar sus propios objetos para representar el evento JSON que pasa a la función de Lambda. El tiempo de ejecución administrado intenta serializar el JSON en una nueva instancia del objeto con su comportamiento predeterminado. Si el serializador predeterminado no tiene el comportamiento deseado para el caso de uso, use la serialización personalizada.

Por ejemplo, supongamos que su controlador de funciones espera una clase `Vehicle` como entrada, con la siguiente estructura:

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

Sin embargo, la carga útil del evento JSON tiene este aspecto:

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

En este escenario, la serialización predeterminada en el tiempo de ejecución administrado espera que los nombres de las propiedades de JSON coincidan con los nombres de propiedad de las clases de Java en mayúsculas y minúsculas (`vehicleType`, `vehicleId`). Como los nombres de las propiedades del evento JSON no usan el formato camelCase (`vehicle-type`,`vehicleID`), debe usar una serialización personalizada.

## Implementación de una serialización personalizada
<a name="implement-custom-serialization"></a>

Utilice una [interfaz del proveedor de servicios](https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html) para cargar el serializador que elija en lugar de la lógica de serialización predeterminada del tiempo de ejecución administrado. Puede serializar las cargas útiles de eventos JSON directamente en objetos de Java mediante la interfaz `RequestHandler` estándar.

**Uso de la serialización personalizada en la función Java de Lambda**

1. Agregue la biblioteca [aws-lambda-java-core](https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-core) como una dependencia. Esta biblioteca incluye la interfaz [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), junto con otras definiciones de interfaz para trabajar con Java en Lambda.

1. Cree un archivo con el nombre `com.amazonaws.services.lambda.runtime.CustomPojoSerializer` en el directorio `src/main/resources/META-INF/services/` del proyecto.

1. En este archivo, especifique el nombre completo de la implementación del serializador personalizado, que debe implementar la interfaz `CustomPojoSerializer`. Ejemplo:

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

1. Implementa la interfaz `CustomPojoSerializer` para proporcionar la lógica de serialización personalizada.

1. Utiliza la interfaz `RequestHandler` estándar de la función de Lambda. El tiempo de ejecución administrado utilizará su serializador personalizado.

Para obtener más ejemplos de cómo implementar la serialización personalizada con bibliotecas populares como fastJson, Gson, Moshi y jackson-jr, consulte la muestra [custom-serialization](https://github.com/aws/aws-lambda-java-libs/tree/main/samples/custom-serialization) en el repositorio de GitHub de AWS.

## Prueba de la serialización personalizada
<a name="test-custom-serialization"></a>

Pruebe la función para asegurarse de que la lógica de serialización y deserialización funcione según lo esperado. Puede utilizar la Interfaz de la línea de comandos de AWS Serverless Application Model comandos (CLI de AWS SAM) para emular la invocación de la carga útil de Lambda. Esto puede ayudarle a probar e iterar rápidamente su función a medida que ingresa un serializador personalizado.

1. Cree un archivo con la carga útil del evento JSON con la que desea invocar la función y, a continuación, llame a la CLI de AWS SAM.

1. Ejecute el comando [sam local invoke](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html ) para invocar la función localmente. Ejemplo:

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

Para obtener más información, consulte [Locally invoke Lambda functions with AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-invoke.html).

# Personalice el comportamiento de inicio del tiempo de ejecución de Java para funciones de Lambda
<a name="java-customization"></a>

En esta página, se describe la configuración específica de las funciones de Java en AWS Lambda. Puede utilizar esta configuración para personalizar el comportamiento de inicio del tiempo de ejecución de Java. Esto puede reducir la latencia general de las funciones y mejorar su rendimiento general, sin tener que modificar ningún código.

**Topics**
+ [Cómo entender la variable de entorno `JAVA_TOOL_OPTIONS`](#java-tool-options)
+ [Parche de Log4j para Log4Shell](#log4shell-patch)
+ [Cachés anticipadas (AOT) y CDS](#aot-cds-caches)

## Cómo entender la variable de entorno `JAVA_TOOL_OPTIONS`
<a name="java-tool-options"></a>

En Java, Lambda admite la variable de entorno `JAVA_TOOL_OPTIONS` para establecer variables de línea de comandos adicionales. Puede utilizar esta variable de entorno de varias maneras, como para personalizar la configuración de compilación por niveles. En el siguiente ejemplo, se muestra cómo utilizar la variable de entorno `JAVA_TOOL_OPTIONS` en este caso de uso.

### Ejemplo: cómo personalizar la configuración de compilación por niveles
<a name="tiered-compilation"></a>

La compilación por niveles es una característica de la máquina virtual Java (JVM). Puede utilizar configuraciones específicas de compilación por niveles para aprovechar al máximo la compilación en tiempo de ejecución (JIT) de la JVM. Por lo general, el compilador C1 está optimizado para un inicio rápido. El compilador C2 está optimizado para obtener el mejor rendimiento general, pero también utiliza más memoria y tarda más en lograrlo. Hay 5 niveles diferentes de compilación por niveles. En el nivel 0, la JVM interpreta el código de bytes de Java. En el nivel 4, la JVM usa el compilador C2 para analizar los datos de creación de perfiles recopilados durante el inicio de la aplicación. Con el tiempo, monitorea el uso del código para identificar las mejores optimizaciones.

La personalización del nivel de compilación por niveles puede ayudarlo a ajustar el rendimiento de sus funciones de Java. En el caso de las funciones pequeñas que se ejecutan rápidamente, establecer la compilación por niveles en el nivel 1 puede ayudar a mejorar el rendimiento del arranque en frío al hacer que la JVM utilice el compilador C1. Esta opción produce rápidamente código nativo optimizado, pero no genera ningún dato de creación de perfiles y nunca usa el compilador C2. Para funciones más grandes y con un uso intensivo de cómputo, establecer la compilación por niveles en el nivel 4 maximiza el rendimiento general a expensas del consumo adicional de memoria y del trabajo de optimización adicional durante las primeras invocaciones después de aprovisionar cada entorno de ejecución de Lambda.

Para los tiempos de ejecución de Java 11 y versiones anteriores, Lambda usa la configuración de compilación por niveles predeterminada de la JVM. Para Java 17 y Java 21, Lambda configura la JVM para detener la compilación por niveles en el nivel 1 de forma predeterminada. A partir de Java 25, Lambda sigue deteniendo la compilación por niveles en el nivel 1 de forma predeterminada, excepto cuando se usa SnapStart o la concurrencia aprovisionada, en cuyo caso se usa la configuración predeterminada de la JVM. Esto mejora el rendimiento de SnapStart y la concurrencia aprovisionada sin incurrir en una penalización por arranque en frío, ya que, en estos casos, la compilación por niveles se realiza fuera de la ruta de invocación. Para aprovechar al máximo esta ventaja, puede utilizar las rutas de código de preparación-ejecución durante la inicialización de la función para activar el JIT antes de tomar la instantánea de SnapStart o cuando los entornos de ejecución con concurrencia aprovisionada están aprovisionados previamente. Para obtener más información, consulte la entrada del blog [Optimizing cold start performance of AWS Lambda using advanced priming strategies with SnapStart](https://aws.amazon.com/blogs/compute/optimizing-cold-start-performance-of-aws-lambda-using-advanced-priming-strategies-with-snapstart/).

**Para personalizar la configuración de compilación por niveles (consola)**

1. Abra la página [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija la función de Java para la que desea personalizar la compilación por niveles.

1. Elija la pestaña **Configuración** y, a continuación, elija **Variables de entorno** en el menú de la izquierda.

1. Elija **Editar**.

1. Elija **Add environment variable** (Añadir variable de entorno).

1.  Para la clave, ingrese `JAVA_TOOL_OPTIONS`. Para el valor, ingrese `-XX:+TieredCompilation -XX:TieredStopAtLevel=1`.   
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/java-tool-options-tiered-compilation.png)

1. Seleccione **Save**.

**nota**  
También puede utilizar Lambda SnapStart para mitigar los problemas de arranque en frío. SnapStart utiliza instantáneas almacenadas en caché de su entorno de ejecución para mejorar de forma significativa el rendimiento de inicio. Para obtener más información sobre las características, las limitaciones y las regiones admitidas de SnapStart, consulte [Mejora del rendimiento de inicio con Lambda SnapStart](snapstart.md).

### Ejemplo: personalización del comportamiento de GC mediante JAVA\$1TOOL\$1OPTIONS
<a name="gc-behavior"></a>

Los tiempos de ejecución de Java 11 utilizan el recopilador de elementos no utilizados (GC) [en serie](https://docs.oracle.com/en/java/javase/18/gctuning/available-collectors.html#GUID-45794DA6-AB96-4856-A96D-FDE5F7DEE498) para la recopilación de elementos no utilizados. De forma predeterminada, los tiempos de ejecución de Java 17 también utilizan el GC en serie. Sin embargo, con Java 17 también puede usar la variable de entorno `JAVA_TOOL_OPTIONS` para cambiar el GC predeterminado. Puede elegir entre el GC en paralelo y el [GC Shenandoah](https://wiki.openjdk.org/display/shenandoah/Main).

Por ejemplo, si su carga de trabajo utiliza más memoria y varias CPU, considere la posibilidad de utilizar el GC en paralelo para obtener un mejor rendimiento. Para ello, agregue lo siguiente al valor de la variable de entorno `JAVA_TOOL_OPTIONS`:

```
-XX:+UseParallelGC
```

Si su carga de trabajo tiene muchos objetos de corta duración, puede beneficiarse de un menor consumo de memoria si habilita el modo generacional del recolector de basura Shenandoah introducido en Java 25. Para ello, agregue lo siguiente al valor de la variable de entorno `JAVA_TOOL_OPTIONS`:

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

## Parche de Log4j para Log4Shell
<a name="log4shell-patch"></a>

Los tiempos de ejecución de Lambda para Java 8, 11, 17 y 21 incluyen un parche para mitigar la vulnerabilidad de Log4Shell (CVE-2021-44228) en Log4j, un popular marco de registro de Java. Este parche supone una sobrecarga de rendimiento al arrancar en frío. Si utiliza una versión parcheada de Log4j (versión 2.17.0 o posterior), puede deshabilitar este parche para mejorar el rendimiento del arranque en frío. Para deshabilitar el parche, configure la variable de entorno `AWS_LAMBDA_DISABLE_CVE_2021_44228_PROTECTION` en `true`.

A partir de Java 25, los tiempos de ejecución de Lambda ya no incluyen el parche Log4Shell. Debe comprobar que está utilizando la versión 2.17.0 o posterior de Log4j.

## Cachés anticipadas (AOT) y CDS
<a name="aot-cds-caches"></a>

A partir de Java 25, el entorno de ejecución de Lambda incluye una caché anticipada (AOT) para el cliente de interfaz de ejecución (RIC) de Java, un componente de tiempo de ejecución que sondea activamente los eventos de la API de tiempo de ejecución de Lambda. Esto mejora el rendimiento del arranque en frío.

Las cachés AOT son específicas de una compilación de JVM. Cuando Lambda actualiza el tiempo de ejecución administrado, también actualiza la caché AOT del RIC. Sin embargo, si implementa sus propias cachés AOT, estas pueden invalidarse o provocar un comportamiento inesperado tras una actualización del tiempo de ejecución. Por lo tanto, recomendamos encarecidamente no utilizar cachés AOT cuando se utilicen tiempos de ejecución administrados. Para usar las cachés AOT, debe implementar las funciones mediante imágenes de contenedor.

Las cachés AOT no se pueden usar con las cachés de intercambio de datos de clase (CDS). Si implementa cachés CDS en su función de Lambda, Lambda deshabilita la caché AOT.

# Uso del objeto de contexto Lambda para recuperar información de funciones de Java
<a name="java-context"></a>

Cuando Lambda ejecuta su función, pasa un objeto context al [controlador](java-handler.md). Este objeto proporciona métodos y propiedades que facilitan información acerca de la invocación, la función y el entorno de ejecución.

**Métodos de context**
+ `getRemainingTimeInMillis()`: devuelve el número de milisegundos que quedan antes del tiempo de espera de la ejecución.
+ `getFunctionName()`: el nombre de la función de Lambda.
+ `getFunctionVersion()`: devuelve la [version](configuration-versions.md) de la función.
+ `getInvokedFunctionArn()`: devuelve el nombre de recurso de Amazon (ARN) que se utiliza para invocar la función. Indica si el invocador especificó un número de versión o alias.
+ `getMemoryLimitInMB()`: devuelve la cantidad de memoria asignada a la función.
+ `getAwsRequestId()`: devuelve el identificador de la solicitud de invocación.
+ `getLogGroupName()`: devuelve el grupo de registros de para la función.
+ `getLogStreamName()`: devuelve el flujo de registro de la instancia de la función.
+ `getIdentity()`: (aplicaciones móviles) devuelve la información acerca de la identidad de Amazon Cognito que autorizó la solicitud.
+ `getClientContext()`: (aplicaciones móviles) devuelve el contexto de cliente proporcionado a Lambda por la aplicación cliente.
+ `getLogger()`: devuelve el [objeto logger](java-logging.md) para la función.

En el ejemplo siguiente, se muestra una función que utiliza el objeto contextual para acceder al registrador de 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;
  }
}
```

La función registra el tipo de clase del evento entrante antes de volver a `null`.

**Example salida del registro**  

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

La interfaz del objeto contextual está disponible en la biblioteca [aws-lambda-java-core](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-core). Puede implementar esta interfaz para crear una clase contextual para las pruebas. En el ejemplo siguiente, se muestra una clase contextual que devuelve valores ficticios para la mayoría de las propiedades y un registrador de pruebas en funcionamiento.

**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 obtener más información sobre los registros, consulte [Registro y supervisión de las funciones de Lambda de Java](java-logging.md).

## Contexto en aplicaciones de ejemplo
<a name="java-context-samples"></a>

El repositorio de GitHub para esta guía contiene aplicaciones de ejemplo en las que se muestra el uso del objeto contextual. Cada una de las aplicaciones de ejemplo contiene scripts para facilitar la implementación y la limpieza, una plantilla de AWS Serverless Application Model (AWS SAM) y recursos de soporte.

**Aplicaciones de Lambda de ejemplo en Java**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java): función de Java que demuestra cómo se puede utilizar Lambda para procesar pedidos. Esta función muestra cómo definir y deserializar un objeto de evento de entrada personalizado, cómo usar el SDK de AWS y cómo registrar los resultados.
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic): una colección de funciones de Java mínimas con pruebas unitarias y configuración de registro variable.
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events): una colección de funciones Java que contiene un código básico sobre cómo gestionar los eventos de varios servicios, como Amazon API Gateway, Amazon SQS y Amazon Kinesis. Estas funciones utilizan la última versión de la biblioteca [aws-lambda-java-events](java-package.md) (3.0.0 y más recientes). Estos ejemplos no requieren utilizar AWS SDK como una dependencia.
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java): una función de Java que procesa los eventos de notificación de Amazon S3 y utiliza Java Class Library (JCL) para crear miniaturas de los archivos de imagen cargados.
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java): función de Java que ilustra cómo utilizar una capa de Lambda para empaquetar las dependencias de forma separada del código de la función principal.

# Registro y supervisión de las funciones de Lambda de Java
<a name="java-logging"></a>

AWS Lambda supervisa de forma automática funciones de Lambda y envía entradas de registros a Amazon CloudWatch. Su función de Lambda viene con un grupo de registros de Registros de CloudWatch y con un flujo de registro para cada instancia de su función. El entorno de tiempo de ejecución de Lambda envía detalles sobre cada invocación y otros resultados del código de su función al flujo de registro. Para obtener más información acerca de Registros de CloudWatch, consulte [Envío de registros de funciones de Lambda a Registros de CloudWatch](monitoring-cloudwatchlogs.md).

Para generar registros desde el código de función, puede utilizar los métodos de [java.lang.System](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html) o cualquier módulo de registro que escriba en stdout o stderr.

**Topics**
+ [Crear una función que devuelve registros](#java-logging-output)
+ [Uso de los controles de registro avanzados de Lambda con Java](#java-logging-advanced)
+ [Implementación del registro avanzado con Log4j2 y SLF4J](#java-logging-log4j2)
+ [Uso de otras herramientas y bibliotecas de registro](#java-tools-libraries)
+ [Uso de Powertools para AWS Lambda (Java) y AWS SAM para el registro estructurado](#java-logging-sam)
+ [Visualización de los registros en la consola de Lambda](#java-logging-console)
+ [Visualización de los registros de en la consola de CloudWatch](#java-logging-cwconsole)
+ [Visualización de los registros mediante la AWS Command Line Interface (AWS CLI)](#java-logging-cli)
+ [Eliminación de registros](#java-logging-delete)
+ [Código de registro de ejemplo](#java-logging-samples)

## Crear una función que devuelve registros
<a name="java-logging-output"></a>

Para generar registros desde el código de función, puede utilizar los métodos de [java.lang.System](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html) o cualquier módulo de registro que escriba en `stdout` o `stderr`. La biblioteca [aws-lambda-java-core](java-package.md) tiene una clase de registrador llamada `LambdaLogger` a la que se puede acceder desde el objeto contextual. La clase de registrador admite registros multilínea.

En el ejemplo siguiente se utiliza el registrador `LambdaLogger` proporcionado por el objeto contextual.

**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 de registro**  

```
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
```

El tiempo de ejecución de Java registra las líneas `START`, `END` y `REPORT` de cada invocación. La línea del informe proporciona los siguientes detalles:

**Campos de datos de línea REPORT**
+ **RequestId**: el ID de solicitud único para la invocación.
+ **Duración**: la cantidad de tiempo que el método de controlador de función pasó procesando el evento.
+ **Duración facturada**: la cantidad de tiempo facturado por la invocación.
+ **Tamaño de memoria**: la cantidad de memoria asignada a la función.
+ **Máximo de memoria usada**: la cantidad de memoria utilizada por la función. Cuando las invocaciones comparten un entorno de ejecución, Lambda informa de la memoria máxima utilizada en todas las invocaciones. Este comportamiento puede dar como resultado un valor notificado superior al esperado.
+ **Duración de inicio**: para la primera solicitud servida, la cantidad de tiempo que tardó el tiempo de ejecución en cargar la función y ejecutar código fuera del método del controlador.
+ **TraceId de XRAY**: para las solicitudes rastreadas, el [ID de seguimientode AWS X-Ray](services-xray.md).
+ **SegmentId**: para solicitudes rastreadas, el ID del segmento de X-Ray.
+ **Muestras**: para solicitudes rastreadas, el resultado del muestreo.

## Uso de los controles de registro avanzados de Lambda con Java
<a name="java-logging-advanced"></a>

Para tener más control sobre cómo se registran, procesan y consumen los registros de las funciones, puede configurar las siguientes opciones de registro para los tiempos de ejecución de Java admitidos:
+ **Formato de registro**: seleccione entre texto sin formato y el formato JSON estructurado para los registros de su función
+ **Nivel de registro**: para los registros en formato JSON, elija el nivel de detalle de los registros que Lambda envía a CloudWatch, como ERROR, DEBUG o INFO
+ **Grupo de registro**: elija el grupo de registro de CloudWatch al que su función envía los registros

Para obtener más información sobre estas opciones de registro e instrucciones sobre cómo configurar la función para utilizarlas, consulte [Configuración de controles de registro avanzados para las funciones de Lambda](monitoring-logs.md#monitoring-cloudwatchlogs-advanced).

Para utilizar las opciones de formato de registro y nivel de registro con las funciones de Lambda de Java, consulte las instrucciones en las siguientes secciones.

### Uso del formato de registro JSON estructurado con Java
<a name="java-logging-advanced-JSON"></a>

Si selecciona JSON para el formato de registro de la función, Lambda enviará los registros de salida utilizando la clase `LambdaLogger` como JSON estructurado. Cada objeto de registro JSON contiene, por lo menos, cuatro pares clave-valor con las siguientes claves:
+ `"timestamp"`: la hora en que se generó el mensaje de registro
+ `"level"`: el nivel de registro asignado al mensaje
+ `"message"`: el contenido del mensaje de registro
+ `"AWSrequestId"`: el ID de solicitud único para la invocación de la función

Según el método de registro que utilice, las salidas de registro de la función capturadas en formato JSON también pueden contener pares de clave-valor adicionales.

Para asignar un nivel a los registros que cree con el registrador `LambdaLogger`, debe proporcionar un argumento `LogLevel` en el comando de registro, como se muestra en el siguiente ejemplo.

**Example Código de registro Java**  

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

Este registro generado por este código de ejemplo sería capturado en los Registros de CloudWatch de la siguiente manera:

**Example Entrada de registro JSON**  

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

Si no asigna un nivel a la salida del registro, Lambda asignará el nivel INFO automáticamente.

Si su código ya usa otra biblioteca de registro para generar registros con JSON estructurado, no necesita hacer ningún cambio. Lambda no codifica dos veces ningún registro que ya esté codificado en JSON. Incluso si configura su función para utilizar el formato de registro JSON, las salidas del registro aparecen en CloudWatch en la estructura JSON que defina.

### Uso del filtrado a nivel de registro con Java
<a name="java-logging-advanced-levels"></a>

Para que AWS Lambda filtre los registros de las aplicaciones según su nivel de registro, la función debe usar registros con formato JSON. Puede lograr esto de dos maneras:
+ Cree salidas de registro con el estándar `LambdaLogger` y configure su función para que utilice el formato de registro JSON. Lambda, a continuación, filtra los resultados del registro mediante el par clave-valor de “nivel” del objeto JSON que se describe en [Uso del formato de registro JSON estructurado con Java](#java-logging-advanced-JSON). Para obtener información sobre cómo configurar el formato de registro de la función, consulte [Configuración de controles de registro avanzados para las funciones de Lambda](monitoring-logs.md#monitoring-cloudwatchlogs-advanced).
+ Utilice otra biblioteca o método de registro para crear registros estructurados en JSON en su código que incluyan un par clave-valor “nivel” que defina el nivel de la salida del registro. También puede utilizar cualquier biblioteca de registro que pueda escribir registros JSON en `stdout` o `stderr`. Por ejemplo, puede utilizar Powertools para AWS Lambda o el paquete Log4j2 para generar salidas de registros estructurados JSON a partir de su código. Consulte [Uso de Powertools para AWS Lambda (Java) y AWS SAM para el registro estructurado](#java-logging-sam) y [Implementación del registro avanzado con Log4j2 y SLF4J](#java-logging-log4j2) para obtener más información.

Cuando configura la función para que utilice el filtrado a nivel de registro, debe seleccionar una de las siguientes opciones para el nivel de registros que desea que Lambda envíe a los Registros de CloudWatch:


| Nivel de registro | Uso estándar | 
| --- | --- | 
| TRACE (más detallado) | La información más detallada que se utiliza para rastrear la ruta de ejecución del código | 
| DEBUG | Información detallada para la depuración del sistema | 
| INFO | Mensajes que registran el funcionamiento normal de su función | 
| WARN | Mensajes sobre posibles errores que pueden provocar un comportamiento inesperado si no se abordan | 
| ERROR | Mensajes sobre problemas que impiden que el código funcione según lo esperado | 
| FATAL (menos detallado) | Mensajes sobre errores graves que hacen que la aplicación deje de funcionar | 

Para que Lambda filtre los registros de la función, también debe incluir un par clave-valor `"timestamp"` en la salida del registro JSON. La hora debe especificarse con un formato de marca de tiempo [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) válido. Si no proporciona una marca de tiempo válida, Lambda asignará al registro el nivel INFO y agregará una marca de tiempo por usted.

Lambda envía los registros del nivel seleccionado y en un nivel inferior a CloudWatch. Por ejemplo, si configura un nivel de registro de WARN, Lambda enviará los registros correspondientes a los niveles WARN, ERROR y FATAL.

## Implementación del registro avanzado con Log4j2 y SLF4J
<a name="java-logging-log4j2"></a>

**nota**  
 AWS Lambda no incluye Log4j2 en los tiempos de ejecución administrados ni en las imágenes de contenedores base. Por lo tanto, no se ven afectados por los problemas descritos en CVE-2021-44228, CVE-2021-45046 y CVE-2021-45105.   
 En los casos en los que una función de cliente incluya una versión de Log4j2 afectada, hemos aplicado cambios a los [tiempos de ejecución administrados](lambda-runtimes.md) de Java y las [imágenes de contenedores base](java-image.md) de Lambda para poder mitigar los problemas de CVE-2021-44228, CVE-2021-45046 y CVE-2021-45105. Como resultado de este cambio, los clientes que utilizan Log4J2 pueden ver una entrada de registro adicional, similar a “”. "`Transforming org/apache/logging/log4j/core/lookup/JndiLookup (java.net.URLClassLoader@...)`". Cualquier cadena de registro que haga referencia al asignador jndi en la salida de Log4J2 se reemplazará por “”. "`Patched JndiLookup::lookup()`".   
 Independientemente de este cambio, recomendamos encarecidamente a todos los clientes cuyas funciones incluyan Log4j2 que actualicen a la última versión. En concreto, los clientes que utilicen la biblioteca aws-lambda-java-log4j2 en sus funciones deben actualizar a la versión 1.5.0 (o posterior) y volver a implementarlas. Esta versión actualiza las dependencias de la utilidad Log4j2 subyacentes a la versión 2.17.0 (o posterior). El binario aws-lambda-java-log4j2 actualizado está disponible en el [repositorio de Maven](https://repo1.maven.org/maven2/com/amazonaws/aws-lambda-java-log4j2/) y su código fuente está disponible en [GitHub](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-log4j2).   
 Por último, tenga en cuenta que las bibliotecas relacionadas con **aws-lambda-java-log4j (v1.0.0 o 1.0.1**) **no** deben usarse por **ningún** motivo. Estas bibliotecas están relacionadas con la versión 1.x de log4j, que dejó de estar disponible en 2015. Las bibliotecas no son compatibles, no se mantienen ni están parcheadas y tienen vulnerabilidades de seguridad conocidas. 

Para personalizar la salida del registro, posibilitar el registro durante las pruebas unitarias y registrar las llamadas del AWS SDK, utilice Apache Log4j2 con SLF4J. Log4j es una biblioteca de registros para programas Java que permite configurar diversos niveles de registro y utilizar bibliotecas de appender. SLF4J es una biblioteca de fachadas que permite cambiar la biblioteca empleada sin modificar el código de la función.

Para agregar el ID de la solicitud a los registros de la función, use el appender de la 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): configuración de 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>
```

Puede decidir cómo se configuran sus registros de Log4j2 para las salidas de texto plano o JSON especificando un diseño debajo en las etiquetas `<LambdaTextFormat>` y `<LambdaJSONFormat>`.

Con esta configuración, en el modo texto, en cada línea se antepone la fecha, la hora, el ID de la solicitud, el nivel de registro y el nombre de la clase. En el modo JSON, `<JsonTemplateLayout>` se usa con una configuración que se incluye junto con la biblioteca `aws-lambda-java-log4j2`.

SLF4J es una biblioteca de fachadas para los registros de código Java. En el código de la función, se utiliza la fábrica del registrador de SLF4J para recuperar un registrador con métodos para niveles de registro como `info()` y `warn()`. En la configuración de compilación, puede incluir la biblioteca de registros y el adaptador de SLF4J en el classpath. Si cambia las bibliotecas en la configuración de compilación, puede cambiar el tipo de registrador sin necesidad de modificar el código de la función. Es necesario utilizar SLF4J para capturar registros de SDK para Java.

En el siguiente código de ejemplo, la clase de controlador utiliza SLF4J para recuperar un registrador.

**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 con 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";
    }
}
```

Este código produce salidas del registro similares a las siguientes:

**Example formato de registro**  

```
{
    "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/"
}
```

La configuración de compilación toma dependencias del tiempo de ejecución del appender de Lambda y del adaptador de SLF4J, y dependencias de implementación de Log4J2.

**Example build.gradle: dependencias de registro**  

```
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,)',
    ...
}
```

Cuando ejecuta el código localmente para realizar pruebas, el objeto contextual con el registrador de Lambda no está disponible y no hay ningún ID de solicitud que el appender de Lambda pueda utilizar. Para ver ejemplos de configuraciones de prueba, consulte las aplicaciones de la siguiente sección. 

## Uso de otras herramientas y bibliotecas de registro
<a name="java-tools-libraries"></a>

[Powertools para AWS Lambda (Java)](https://docs.aws.amazon.com/powertools/java/) es un kit de herramientas para desarrolladores destinado a implementar prácticas recomendadas sin servidor y aumentar la velocidad de los desarrolladores. La [utilidad de registro](https://docs.aws.amazon.com/powertools/java/latest/core/logging/) proporciona un logger optimizado para Lambda que incluye información adicional sobre el contexto de la función en todas las funciones con un resultado estructurado como JSON. Utilice esta utilidad para hacer lo siguiente:
+ Capturar campos clave del contexto de Lambda, arranque en frío y resultados de registro de estructuras como JSON
+ Registrar los eventos de invocación de Lambda cuando se le indique (desactivado de forma predeterminada)
+ Imprimir todos los registros solo para un porcentaje de las invocaciones mediante el muestreo de registros (desactivado de forma predeterminada)
+ Agregar claves adicionales al registro estructurado en cualquier momento
+ Utilizar un formateador de registros personalizado (traiga su propio formateador) para generar registros en una estructura compatible con el RFC de registro de su organización

## Uso de Powertools para AWS Lambda (Java) y AWS SAM para el registro estructurado
<a name="java-logging-sam"></a>

Siga los pasos que figuran a continuación para descargar, crear e implementar una aplicación de muestra “Hola, mundo” de Java con módulos de [Powertools para AWS Lambda (Java)](https://docs.aws.amazon.com/powertools/java/latest/) integrados mediante AWS SAM. Esta aplicación implementa un backend de API básico y utiliza Powertools para emitir registros, métricas y seguimiento. Consta de un punto de conexión de Amazon API Gateway y una función de Lambda. Cuando se envía una solicitud GET al punto de conexión de API Gateway, la función de Lambda se invoca, envía registros y métricas a CloudWatch mediante Embedded Metric Format y envía seguimiento a AWS X-Ray. La función devuelve el mensaje `hello world`.

**Requisitos previos**

Para completar los pasos de esta sección, debe disponer de lo siguiente:
+ Java 11
+ [AWS CLI versión 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM Versión 1.75 o posterior de la CLI de](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Si tiene una versión anterior de la CLI de AWS SAM, consulte [Actualización de la CLI de AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Implementar una aplicación de ejemplo de AWS SAM**

1. Inicialice la aplicación con la plantilla “Hola, mundo” de Java.

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

1. Compile la aplicación.

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

1. Implemente la aplicación.

   ```
   sam deploy --guided
   ```

1. Siga las indicaciones que aparecen en pantalla. Para aceptar las opciones predeterminadas proporcionadas en la experiencia interactiva, oprima `Enter`.
**nota**  
En **HelloWorldFunction es posible que no tenga definida la autorización, ¿está bien?**, asegúrese de ingresar `y`.

1. Obtenga la URL de la aplicación implementada:

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

1. Invoque el punto de conexión de la API:

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

   Si se realiza de forma correcta, verá el siguiente resultado:

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

1. Para obtener los registros de la función, ejecute [sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html). Para obtener más información, consulte [Uso de registros](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html) en la *Guía para desarrolladores de AWS Serverless Application Model*.

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

   El resultado del registro tendrá este aspecto:

   ```
   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. Se trata de un punto de conexión de API pública al que se puede acceder a través de Internet. Se recomienda eliminar el punto de conexión después de las pruebas.

   ```
   sam delete
   ```

### Administración de retención de registros
<a name="java-log-retention"></a>

Los grupos de registro no se eliminan automáticamente cuando se elimina una función. Para evitar almacenar registros de forma indefinida, elimine el grupo de registros o configure un periodo de retención después del cual CloudWatch los eliminará de forma automática. Para configurar la retención de registros, agregue lo siguiente a la plantilla de 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
```

## Visualización de los registros en la consola de Lambda
<a name="java-logging-console"></a>

Puede utilizar la consola de Lambda para ver la salida del registro después de invocar una función de Lambda.

Si su código se puede probar desde el editor de **código** integrado, encontrará los registros en los **resultados de ejecución**. Cuando utilice la característica de prueba de la consola para invocar una función, encontrará la **Salida de registro** en la sección de **Detalles**.

## Visualización de los registros de en la consola de CloudWatch
<a name="java-logging-cwconsole"></a>

Puede utilizar la consola Amazon CloudWatch para ver los registros de todas las invocaciones de funciones de Lambda.

**Visualización de los registros en la consola CloudWatch**

1. En la consola de CloudWatch, abra la [página de grupos de registro](https://console.aws.amazon.com/cloudwatch/home?#logs:).

1. Seleccione el grupo de registros para su función (**/aws/lambda/*your-function-name***).

1. Elija una secuencia de registro.

Cada flujo de registro se corresponde con una [instancia de su función](lambda-runtime-environment.md). Aparece un flujo de registro cuando actualiza la función de Lambda y cuando se crean instancias adicionales para gestionar invocaciones simultáneas. Para encontrar registros para una invocación específica, le recomendamos que interfiera su función con AWS X-Ray. X-Ray registra los detalles sobre la solicitud y el flujo de registro en el seguimiento.

## Visualización de los registros mediante la AWS Command Line Interface (AWS CLI)
<a name="java-logging-cli"></a>

La AWS CLI es una herramienta de código abierto que lo habilita para interactuar con los servicios de AWS mediante el uso de comandos en el intérprete de comandos de la línea de comandos. Para completar los pasos de esta sección, debe disponer de la [versión 2 de la AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

Puede utilizar la [CLI de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) para recuperar registros de una invocación mediante la opción de comando `--log-type`. La respuesta contiene un campo `LogResult` que contiene hasta 4 KB de registros con codificación base64 a partir de la invocación.

**Example recuperar un ID de registro**  
En el ejemplo siguiente se muestra cómo recuperar un *ID de registro* del campo `LogResult` para una función denominada `my-function`.  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
Debería ver los siguientes datos de salida:  

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

**Example decodificar los registros**  
En el mismo símbolo del sistema, utilice la utilidad `base64` para decodificar los registros. En el ejemplo siguiente se muestra cómo recuperar registros codificados en base64 para `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
```
La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 2*.  
Debería ver los siguientes datos de salida:  

```
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
```
La utilidad `base64` está disponible en Linux, macOS y [Ubuntu en Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10). Es posible que los usuarios de macOS necesiten usar `base64 -D`.

**Example get-logs.sh script**  
En el mismo símbolo del sistema, utilice el siguiente script para descargar los últimos cinco eventos de registro. El script utiliza `sed` para eliminar las comillas del archivo de salida y permanece inactivo durante 15 segundos para dar tiempo a que los registros estén disponibles. La salida incluye la respuesta de Lambda y la salida del comando `get-log-events`.   
Copie el contenido de la siguiente muestra de código y guárdelo en su directorio de proyecto Lambda como `get-logs.sh`.  
La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 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 y Linux (solamente)**  
En el mismo símbolo del sistema, es posible que los usuarios de macOS y Linux necesiten ejecutar el siguiente comando para asegurarse de que el script es ejecutable.  

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

**Example recuperar los últimos cinco eventos de registro**  
En el mismo símbolo del sistema, ejecute el siguiente script para obtener los últimos cinco eventos de registro.  

```
./get-logs.sh
```
Debería ver los siguientes datos de salida:  

```
{
    "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"
}
```

## Eliminación de registros
<a name="java-logging-delete"></a>

Los grupos de registro no se eliminan automáticamente cuando se elimina una función. Para evitar almacenar registros indefinidamente, elimine el grupo de registros o [configure un periodo de retención](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention) después de lo cual los registros se eliminan automáticamente.

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

El repositorio de GitHub para esta guía contiene aplicaciones de ejemplo en las que se muestra el uso de diferentes configuraciones de registro. Cada una de las aplicaciones de ejemplo contiene scripts para facilitar la implementación y la limpieza, una plantilla de AWS SAM y recursos de soporte.

**Aplicaciones de Lambda de ejemplo en Java**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java): función de Java que demuestra cómo se puede utilizar Lambda para procesar pedidos. Esta función muestra cómo definir y deserializar un objeto de evento de entrada personalizado, cómo usar el SDK de AWS y cómo registrar los resultados.
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic): una colección de funciones de Java mínimas con pruebas unitarias y configuración de registro variable.
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events): una colección de funciones Java que contiene un código básico sobre cómo gestionar los eventos de varios servicios, como Amazon API Gateway, Amazon SQS y Amazon Kinesis. Estas funciones utilizan la última versión de la biblioteca [aws-lambda-java-events](java-package.md) (3.0.0 y más recientes). Estos ejemplos no requieren utilizar AWS SDK como una dependencia.
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java): una función de Java que procesa los eventos de notificación de Amazon S3 y utiliza Java Class Library (JCL) para crear miniaturas de los archivos de imagen cargados.
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java): función de Java que ilustra cómo utilizar una capa de Lambda para empaquetar las dependencias de forma separada del código de la función principal.

En la aplicación de ejemplo `java-basic`, se muestra una configuración de registro mínima que admite pruebas de registro. El código del controlador utiliza el registrador de `LambdaLogger` proporcionado por el objeto contextual. En el caso de las pruebas, la aplicación utiliza una clase personalizada de `TestLogger` que implementa la interfaz `LambdaLogger` con un registrador de Log4j2. SLF4J se utiliza como fachada para garantizar la compatibilidad con el SDK de AWS. Las bibliotecas de registro se excluyen de la salida de compilación para mantener un tamaño de paquete de implementación pequeño.

# Instrumentación del código Java en AWS Lambda
<a name="java-tracing"></a>

Lambda se integra con AWS X-Ray para permitirle seguir, depurar y optimizar aplicaciones de Lambda. Puede utilizar X-Ray para seguir una solicitud mientras atraviesa los recursos de la aplicación, que pueden incluir funciones de Lambda y otros servicios de AWS.

Para enviar datos de seguimiento a X-Ray, puede utilizar una de estas dos bibliotecas de SDK:
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel): distribución segura, lista para producción y con soporte de AWS del OpenTelemetry (OTel) SDK.
+ [AWS X-Ray SDK para Java](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java.html) – un SDK para generar y enviar datos de seguimiento a X-Ray.
+ [Powertools para AWS Lambda(Java)](https://docs.aws.amazon.com/powertools/java/latest/): un kit de herramientas para desarrolladores destinado a implementar prácticas recomendadas sin servidor y aumentar la velocidad de los desarrolladores.

Cada uno de los SDK ofrecen formas de enviar los datos de telemetría al servicio X-Ray. Tras ello, se puede utilizar X-Ray para consultar, filtrar y obtener información sobre las métricas de rendimiento de la aplicación con el fin de identificar problemas y oportunidades de optimización.

**importante**  
Los SDK de X-Ray y Powertools para AWS Lambda son parte de una solución de instrumentación completamente integrada que ofrece AWS. Las capas Lambda de ADOT forman parte de un estándar que abarca todo el sector para la instrumentación de seguimiento que recopila más datos en general, pero es posible que no sean adecuadas para todos los casos de uso. Puede implementar el seguimiento integral en X-Ray con cualquiera de las soluciones. Para obtener más información sobre cuál elegir, consulte [Elegir entre SDK de AWS Distro para OpenTelemetry y X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing).

**Topics**
+ [Uso de Powertools para AWS Lambda (Java) y AWS SAM para el seguimiento](#java-tracing-sam)
+ [Uso de Powertools para AWS Lambda (Java) y el AWS CDK para el seguimiento](#java-tracing-cdk)
+ [Uso de ADOT para instrumentar las funciones de Java](#java-adot)
+ [Uso del X-Ray SDK para instrumentar las funciones de Java](#java-xray-sdk)
+ [Activación del seguimiento con la consola de Lambda](#java-tracing-console)
+ [Activación del seguimiento con la API de Lambda](#java-tracing-api)
+ [Activación del seguimiento con CloudFormation](#java-tracing-cloudformation)
+ [Interpretación de un seguimiento de X-Ray](#java-tracing-interpretation)
+ [Almacenamiento de dependencias de tiempo de ejecución en una capa (X-Ray SDK)](#java-tracing-layers)
+ [Seguimiento de X-Ray en aplicaciones de ejemplo (X-Ray SDK)](#java-tracing-samples)

## Uso de Powertools para AWS Lambda (Java) y AWS SAM para el seguimiento
<a name="java-tracing-sam"></a>

Siga los pasos que figuran a continuación para descargar, crear e implementar una aplicación de muestra “Hola, mundo” de Java con módulos de [Powertools para AWS Lambda (Java)](https://docs.powertools.aws.dev/lambda-java) integrados mediante AWS SAM. Esta aplicación implementa un backend de API básico y utiliza Powertools para emitir registros, métricas y seguimiento. Consta de un punto de conexión de Amazon API Gateway y una función de Lambda. Cuando se envía una solicitud GET al punto de conexión de API Gateway, la función de Lambda se invoca, envía registros y métricas a CloudWatch mediante Embedded Metric Format y envía seguimiento a AWS X-Ray. La función devuelve el mensaje `hello world`.

**Requisitos previos**

Para completar los pasos de esta sección, debe disponer de lo siguiente:
+ Java 11 o posterior
+ [AWS CLI versión 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM Versión 1.75 o posterior de la CLI de](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Si tiene una versión anterior de la CLI de AWS SAM, consulte [Actualización de la CLI de AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Implementar una aplicación de ejemplo de AWS SAM**

1. Inicialice la aplicación con la plantilla “Hola, mundo” de Java.

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

1. Compile la aplicación.

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

1. Implemente la aplicación.

   ```
   sam deploy --guided
   ```

1. Siga las indicaciones que aparecen en pantalla. Para aceptar las opciones predeterminadas proporcionadas en la experiencia interactiva, oprima `Enter`.
**nota**  
En **HelloWorldFunction es posible que no tenga definida la autorización, ¿está bien?**, asegúrese de ingresar `y`.

1. Obtenga la URL de la aplicación implementada:

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

1. Invoque el punto de conexión de la API:

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

   Si se realiza de forma correcta, verá el siguiente resultado:

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

1. Para obtener el seguimiento de la función, ejecute [sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html).

   ```
   sam traces
   ```

   El resultado del seguimiento tendrá este aspecto:

   ```
   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. Se trata de un punto de conexión de API pública al que se puede acceder a través de Internet. Se recomienda eliminar el punto de conexión después de las pruebas.

   ```
   sam delete
   ```

## Uso de Powertools para AWS Lambda (Java) y el AWS CDK para el seguimiento
<a name="java-tracing-cdk"></a>

Siga los pasos que figuran a continuación para descargar, crear e implementar una aplicación de muestra “Hola, mundo” de Java con módulos de [Powertools para AWS Lambda (Java)](https://docs.powertools.aws.dev/lambda-java) integrados mediante AWS CDK. Esta aplicación implementa un backend de API básico y utiliza Powertools para emitir registros, métricas y seguimiento. Consta de un punto de conexión de Amazon API Gateway y una función de Lambda. Cuando se envía una solicitud GET al punto de conexión de API Gateway, la función de Lambda se invoca, envía registros y métricas a CloudWatch mediante Embedded Metric Format y envía seguimiento a AWS X-Ray. La función devuelve el mensaje hello world.

**Requisitos previos**

Para completar los pasos de esta sección, debe disponer de lo siguiente:
+ Java 11 o posterior
+ [AWS CLI versión 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS CDK versión 2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_prerequisites)
+ [Versión 1.75 o posterior de la CLI de AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Si tiene una versión anterior de la CLI de AWS SAM, consulte [Actualización de la CLI de AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Implementar una aplicación de ejemplo de AWS CDK**

1. Cree un directorio de proyecto para la nueva aplicación.

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

1. Inicialice la aplicación.

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

1. Ejecute el siguiente comando para crear el proyecto de Maven:

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

1. Abra `pom.xml` en el directorio `hello-world\app\Function` y sustituya el código existente por el siguiente código, el cual incluye dependencias y complementos de 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. Cree el directorio `hello-world\app\src\main\resource` y cree `log4j.xml` para la configuración del registro.

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

1. Abra `log4j.xml` y agregue el siguiente código.

   ```
   <?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 `App.java` desde el directorio `hello-world\app\Function\src\main\java\helloworld` y sustituya el código existente por el siguiente código. Se trata del código de la función de 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 `HelloWorldStack.java` desde el directorio `hello-world\src\main\java\com\myorg` y sustituya el código existente por el siguiente código. Este código utiliza el [Constructor de Lambda](https://docs.aws.amazon.com/cdk/api/v1/java/aws_cdk.aws_lambda.html) y el [Constructor de ApiGatewayV2](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigatewayv2-readme.html) para crear una API de REST y una función de 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 `pom.xml` desde el directorio `hello-world` y sustituya el código existente por el siguiente código.

   ```
   <?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. Asegúrese de estar en el directorio `hello-world` e implemente la aplicación.

   ```
   cdk deploy
   ```

1. Obtenga la URL de la aplicación implementada:

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

1. Invoque el punto de conexión de la API:

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

   Si se realiza de forma correcta, verá el siguiente resultado:

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

1. Para obtener el seguimiento de la función, ejecute [sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html).

   ```
   sam traces
   ```

   El resultado del seguimiento tendrá este aspecto:

   ```
   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. Se trata de un punto de conexión de API pública al que se puede acceder a través de Internet. Se recomienda eliminar el punto de conexión después de las pruebas.

   ```
   cdk destroy
   ```

## Uso de ADOT para instrumentar las funciones de Java
<a name="java-adot"></a>

ADOT proporciona [capas](chapter-layers.md) de Lambda completamente administradas que empaquetan todo lo necesario para recopilar datos de telemetría mediante el OTel SDK. Utilizando esta capa, se pueden instrumentar las funciones de Lambda sin tener que modificar el código de ninguna función. También se puede configurar la capa para que realice una inicialización personalizada de OTel. Para obtener más información, consulte [Configuración personalizada del recopilador de ADOT en Lambda](https://aws-otel.github.io/docs/getting-started/lambda#custom-configuration-for-the-adot-collector-on-lambda) en la documentación de ADOT.

Para los tiempos de ejecución de Java, puede elegir entre dos capas:
+ **Capa de Lambda administrada de AWS para ADOT Java (agente de instrumentación automática)**: esta capa transforma automáticamente el código de la función durante el inicio para recopilar datos de seguimiento. Para obtener instrucciones detalladas sobre cómo utilizar esta capa junto con el agente de ADOT Java, consulte [Soporte de Lambda de AWS Distro for OpenTelemetry para Java (agente de instrumentación automática)](https://aws-otel.github.io/docs/getting-started/lambda/lambda-java-auto-instr) en la documentación de ADOT.
+ **Capa de Lambda administrada de AWS para ADOT Java**: esta capa también proporciona instrumentación integrada para las funciones de Lambda, pero requiere algunos cambios de código manuales para inicializar el OTel SDK. Para obtener instrucciones detalladas sobre cómo utilizar esta capa, consulte [Soporte de Lambda de AWS Distro for OpenTelemetry para Java](https://aws-otel.github.io/docs/getting-started/lambda/lambda-java) en la documentación de ADOT.

## Uso del X-Ray SDK para instrumentar las funciones de Java
<a name="java-xray-sdk"></a>

Para registrar datos sobre las llamadas que realiza la función a otros recursos y servicios de la aplicación, se puede agregar el X-Ray SDK para Java a la configuración de compilación. En el siguiente ejemplo, se muestra una configuración de compilación de Gradle que incluye las bibliotecas que activan la instrumentación automática de los clientes de 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): dependencias de seguimiento.**  

```
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'
    ...
}
```

Una vez agregadas las dependencias correctas y realizados los cambios de código necesarios, active el seguimiento en la configuración de la función mediante la consola de Lambda o la API.

## Activación del seguimiento con la consola de Lambda
<a name="java-tracing-console"></a>

Para activar el seguimiento activo de la función Lambda mediante la consola, siga estos pasos:

**Cómo activar el seguimiento activo**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija una función.

1. Elija **Configuration** (Configuración), y luego **Monitoring and operations tools** (Herramientas de supervisión y operaciones).

1. En **Herramientas de monitorización adicionales**, elija **Editar**.

1. En **CloudWatch Application Signals y AWS X-Ray**, seleccione **Habilitar** para **Seguimientos de servicios de Lambda**.

1. Seleccione **Save**.

## Activación del seguimiento con la API de Lambda
<a name="java-tracing-api"></a>

Configure el rastreo en la función Lambda con AWS CLI o SDK de AWS, utilice las siguientes operaciones 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)

El siguiente comando de ejemplo de la AWS CLI habilita el seguimiento activo en una función llamada **my-function**.

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

El modo de seguimiento forma parte de la configuración específica de la versión, cuando se publica una versión de la función. No se puede cambiar el modo de seguimiento de una versión publicada.

## Activación del seguimiento con CloudFormation
<a name="java-tracing-cloudformation"></a>

Para activar el seguimiento en un recurso de `AWS::Lambda::Function` de una plantilla de CloudFormation, utilice la propiedad `TracingConfig`.

**Example [función-inline.yml](https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/templates/function-inline.yml): configuración de rastreo**  

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

Para un recurso AWS Serverless Application Model de AWS SAM (`AWS::Serverless::Function`) , utilice la propiedad `Tracing`.

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml): configuración de rastreo**  

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

## Interpretación de un seguimiento de X-Ray
<a name="java-tracing-interpretation"></a>

La función necesita permiso para cargar datos de rastreo en X-Ray. Cuando activa el rastreo activo en la consola de Lambda, Lambda agrega los permisos necesarios al [rol de ejecución](lambda-intro-execution-role.md) de la función. De lo contrario, agregue la política [AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess) al rol de ejecución.

Después de configurar el seguimiento activo, se pueden observar solicitudes específicas a través de la aplicación. El [gráfico de servicios de X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph) muestra información sobre la aplicación y todos sus componentes. En el siguiente ejemplo, se muestra una aplicación con dos funciones. La función principal procesa eventos y, a veces, devuelve errores. La segunda función de la cadena procesa los errores que aparecen en el primer grupo de registros y utiliza el SDK de AWS para llamar a X-Ray, Amazon Simple Storage Service (Amazon S3) y Registros de Amazon CloudWatch.

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


X-Ray no sigue todas las solicitudes realizadas a la aplicación. X-Ray aplica un algoritmo de muestreo para garantizar que el seguimiento sea eficiente, a la vez que proporciona una muestra representativa de todas las solicitudes. La tasa de muestreo es 1 solicitud por segundo y un 5 por ciento de las solicitudes adicionales. La frecuencia de muestreo de X-Ray no se puede configurar para las funciones.

En X-Ray, un *seguimiento* registra información sobre una solicitud procesada por uno o varios *servicios*. Lambda registra 2 segmentos por seguimiento, lo que crea dos nodos en el gráfico de servicios. La siguiente imagen resalta estos dos nodos:

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


El primer nodo, situado a la izquierda, representa el servicio de Lambda, que recibe la solicitud de invocación. El segundo nodo representa la función Lambda específica. En el siguiente ejemplo, se muestra un seguimiento con estos dos segmentos. Ambos se denominan **my-function**, pero uno tiene un origen de `AWS::Lambda` y el otro tiene origen de `AWS::Lambda::Function`. Si el segmento `AWS::Lambda` muestra un error, el servicio Lambda tuvo un problema. Si el segmento `AWS::Lambda::Function` muestra un error, la función tuvo un problema.

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


En este ejemplo, el segmento `AWS::Lambda::Function` aparece ampliado para mostrar los tres subsegmentos.

**nota**  
AWS está implementando cambios en el servicio Lambda. Debido a estos cambios, es posible que vea pequeñas diferencias entre la estructura y el contenido de los mensajes de registro del sistema y los segmentos de rastro emitidos por diferentes funciones de Lambda en su Cuenta de AWS.  
El rastro de ejemplo que se muestra aquí ilustra el segmento de función de estilo antiguo. Las diferencias entre los segmentos de estilo antiguo y nuevo se describen en los párrafos siguientes.  
Estos cambios se implementarán en las próximas semanas y todas las funciones de todas las Regiones de AWS, excepto en las regiones de China y GovCloud, pasarán a utilizar el nuevo formato de mensajes de registro y segmentos de rastro.

El segmento de función de estilo antiguo contiene los siguientes subsegmentos:
+ **Inicialización**: representa el tiempo dedicado a cargar la función y ejecutar el [código de inicialización](foundation-progmodel.md). Este subsegmento aparece únicamente para el primer evento que procesa cada instancia de la función.
+ **Invocación**: representa el tiempo dedicado a ejecutar el código del controlador.
+ **Sobrecarga**: representa el tiempo que el tiempo de ejecución de Lambda dedica a prepararse para gestionar el siguiente evento.

El segmento de función de estilo nuevo no contiene ningún subsegmento de `Invocation`. En cambio, los subsegmentos de clientes se adjuntan directamente al segmento de la función. Para obtener más información sobre la estructura de los segmentos de funciones de estilo antiguo y nuevo, consulte [Comprensión de los rastros](services-xray.md#services-xray-traces).

**nota**  
Las funciones de [Lambda SnapStart](snapstart.md) también incluyen un subsegmento `Restore`. El subsegmento `Restore` muestra el tiempo que tarda Lambda en restaurar una instantánea, cargar el tiempo de ejecución y ejecutar cualquier [enlace de tiempo de ejecución](snapstart-runtime-hooks.md) posterior a la restauración. El proceso de restauración de instantáneas puede incluir el tiempo dedicado a actividades fuera de la micro VM. Esta vez se informa en el subsegmento `Restore`. No se le cobrará por el tiempo que pase fuera de la micro VM para restaurar una instantánea.

También puede instrumentar clientes HTTP, registrar consultas SQL y crear subsegmentos personalizados con anotaciones y metadatos. Para obtener más información, consulte [AWS X-Ray SDK para Java](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java.html) en la *Guía para desarrolladores de AWS X-Ray*.

**Precios**  
Puede utilizar el seguimiento de X-Ray de manera gratuita cada mes hasta un límite determinado como parte del nivel Gratuito de AWS. A partir de ese umbral, X-Ray realiza cargos por almacenamiento y recuperación del seguimiento. Para más información, consulte [Precios de AWS X-Ray](https://aws.amazon.com/xray/pricing/).

## Almacenamiento de dependencias de tiempo de ejecución en una capa (X-Ray SDK)
<a name="java-tracing-layers"></a>

Si utiliza el X-Ray SDK para instrumentar el código de las funciones de los clientes del SDK de AWS, el paquete de implementación puede llegar a ser bastante grande. Para evitar que se carguen dependencias en tiempo de ejecución cada vez que se actualice el código de las funciones, empaquete el X-Ray SDK en una [capa de Lambda](chapter-layers.md).

En el siguiente ejemplo, se muestra un recurso de `AWS::Serverless::LayerVersion` que almacena el AWS SDK para Java y el X-Ray SDK.

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

```
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
```

Con esta configuración, solo se actualiza la capa de la biblioteca si se modifican las dependencias del tiempo de ejecución. Dado que el paquete de implementación de la función contiene únicamente el código, esto puede ayudar a reducir los tiempos de carga.

Para crear una capa de dependencias, es necesario realizar cambios en la configuración de compilación para generar el archivo de capas antes de la implementación. Para ver un ejemplo práctico, consulte la aplicación de ejemplo [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic) en GitHub.

## Seguimiento de X-Ray en aplicaciones de ejemplo (X-Ray SDK)
<a name="java-tracing-samples"></a>

En el repositorio de GitHub correspondiente a esta guía hay aplicaciones de ejemplo que muestran cómo utilizar el seguimiento de X-Ray. Cada una de las aplicaciones de ejemplo contiene scripts para facilitar la implementación y la limpieza, una plantilla de AWS SAM y recursos de soporte.

**Aplicaciones de Lambda de ejemplo en Java**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java): función de Java que demuestra cómo se puede utilizar Lambda para procesar pedidos. Esta función muestra cómo definir y deserializar un objeto de evento de entrada personalizado, cómo usar el SDK de AWS y cómo registrar los resultados.
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic): una colección de funciones de Java mínimas con pruebas unitarias y configuración de registro variable.
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events): una colección de funciones Java que contiene un código básico sobre cómo gestionar los eventos de varios servicios, como Amazon API Gateway, Amazon SQS y Amazon Kinesis. Estas funciones utilizan la última versión de la biblioteca [aws-lambda-java-events](java-package.md) (3.0.0 y más recientes). Estos ejemplos no requieren utilizar AWS SDK como una dependencia.
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java): una función de Java que procesa los eventos de notificación de Amazon S3 y utiliza Java Class Library (JCL) para crear miniaturas de los archivos de imagen cargados.
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java): función de Java que ilustra cómo utilizar una capa de Lambda para empaquetar las dependencias de forma separada del código de la función principal.

Todas las aplicaciones de ejemplo tienen activado el seguimiento activo de las funciones de Lambda. Por ejemplo, en la aplicación `s3-java`, se muestra la instrumentación automática de los clientes de AWS SDK for Java 2.x, la administración de segmentos para pruebas, subsegmentos personalizados y el uso de capas de Lambda para almacenar dependencias en tiempo de ejecución.

# Aplicaciones de ejemplo de Java para AWS Lambda
<a name="java-samples"></a>

El repositorio de GitHub para esta guía ofrece aplicaciones de ejemplo en las que se muestra el uso de Java en AWS Lambda. Cada una de las aplicaciones de ejemplo contiene scripts para facilitar la implementación y la limpieza, una plantilla de CloudFormation y recursos de soporte.

**Aplicaciones de Lambda de ejemplo en Java**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java): función de Java que demuestra cómo se puede utilizar Lambda para procesar pedidos. Esta función muestra cómo definir y deserializar un objeto de evento de entrada personalizado, cómo usar el SDK de AWS y cómo registrar los resultados.
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic): una colección de funciones de Java mínimas con pruebas unitarias y configuración de registro variable.
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events): una colección de funciones Java que contiene un código básico sobre cómo gestionar los eventos de varios servicios, como Amazon API Gateway, Amazon SQS y Amazon Kinesis. Estas funciones utilizan la última versión de la biblioteca [aws-lambda-java-events](java-package.md) (3.0.0 y más recientes). Estos ejemplos no requieren utilizar AWS SDK como una dependencia.
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java): una función de Java que procesa los eventos de notificación de Amazon S3 y utiliza Java Class Library (JCL) para crear miniaturas de los archivos de imagen cargados.
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java): función de Java que ilustra cómo utilizar una capa de Lambda para empaquetar las dependencias de forma separada del código de la función principal.

**Ejecución de marcos Java populares en Lambda**
+ [spring-cloud-function-samples](https://github.com/spring-cloud/spring-cloud-function/tree/3.2.x/spring-cloud-function-samples/function-sample-aws): un ejemplo de Spring que muestra cómo utilizar el marco [Spring Cloud Function](https://spring.io/projects/spring-cloud-function) para crear funciones de Lambda AWS. 
+ [Demostración de la aplicación Spring Boot sin servidor](https://github.com/aws-samples/serverless-java-frameworks-samples/tree/main/springboot): un ejemplo que muestra cómo configurar una aplicación Spring Boot típica en un tiempo de ejecución Java gestionado con y sin SnapStart, o como una imagen nativa de GraalVM con un tiempo de ejecución personalizado.
+ [Demostración de la aplicación MIcronaut sin servidor](https://github.com/aws-samples/serverless-java-frameworks-samples/tree/main/micronaut): un ejemplo que muestra cómo usar Micronaut en un tiempo de ejecución Java gestionado con y sin SnapStart, o como una imagen nativa de GraalVM con un tiempo de ejecución personalizado. Obtenga más información en las [guías de Micronaut/Lambda](https://guides.micronaut.io/latest/tag-lambda.html).
+ [Demostración de la aplicación Quarkus sin servidor](https://github.com/aws-samples/serverless-java-frameworks-samples/tree/main/quarkus): un ejemplo que muestra cómo usar Quarkus en un tiempo de ejecución Java gestionado con y sin SnapStart, o como una imagen nativa de GraalVM con un tiempo de ejecución personalizado. [Obtenga más información en la [guía de Quarkus/Lambda y en la guía de Quarkus/SnapStart](https://quarkus.io/guides/aws-lambda).](https://quarkus.io/guides/aws-lambda-snapstart)

Si es la primera vez que utiliza las funciones de Lambda en Java, comience con los ejemplos de `java-basic`. Para comenzar con los orígenes de eventos de Lambda, consulte los ejemplos de `java-events`. Ambos conjuntos de ejemplos muestran el uso de las bibliotecas Java de Lambda, las variables de entorno, el SDK de AWS y el AWS X-Ray SDK. Estos ejemplos requieren una configuración mínima y puede implementarlos desde la línea de comandos en menos de un minuto.