

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 .zip 或 JAR 封存檔部署 Java Lambda 函數
<a name="java-package"></a>

 AWS Lambda 函數的程式碼包含指令碼或編譯的程式及其相依性。使用*部署套件*將函數程式碼部署到 Lambda。Lambda 支援兩種類型的部署套件：容器映像和 .zip 封存檔。

此頁面說明如何將部署套件建立為 .zip 檔案或 Jar 檔案，然後使用部署套件， AWS Lambda 使用 AWS Command Line Interface (AWS CLI) 將函數程式碼部署至 。

**重要**  
Java 25 引進Ahead-of-Time(AOT) 快取的支援。強烈建議在將函數部署為 .zip 或 JAR 檔案封存時不要使用 AOT 快取，因為當 Lambda 更新受管執行時間時，快取可能會導致非預期的行為。如需詳細資訊，請參閱 [Ahead-of-Time(AOT) 和 CDS 快取](java-customization.md#aot-cds-caches)。

**Topics**
+ [

## 先決條件
](#java-package-prereqs)
+ [

## 工具與程式庫
](#java-package-libraries)
+ [

## 使用 Gradle 建立部署套件
](#java-package-gradle)
+ [

## 使用層來管理相依項
](#java-package-layers)
+ [

## 使用 Maven 建立部署套件
](#java-package-maven)
+ [

## 使用 Lambda 主控台上傳部署套件
](#java-package-console)
+ [

## 使用 上傳部署套件 AWS CLI
](#java-package-cli)
+ [

## 使用 上傳部署套件 AWS SAM
](#java-package-cloudformation)

## 先決條件
<a name="java-package-prereqs"></a>

 AWS CLI 是一種開放原始碼工具，可讓您使用命令列 Shell 中的 命令與 AWS 服務互動。若要完成本節中的步驟，您必須擁有 [AWS CLI 版本 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

## 工具與程式庫
<a name="java-package-libraries"></a>

AWS 為 Java 函數提供下列程式庫。這些程式庫可透過 [Maven Central Repository](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) (必要) - 定義處理常式方法介面，以及執行期傳遞給處理常式的內容物件。如果您定義自己的輸入類型，這是您需要的唯一程式庫。
+ [com.amazonaws:aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-events) - 來自調用 Lambda 函數的服務的輸入事件類型。
+ [com.amazonaws:aws-lambda-java-log4j2](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-log4j2) - 一個 Apache Log4j 2 的附加程式庫，您可以使用它將當前調用的請求 ID 新增至[函數日誌](java-logging.md)。
+ [AWS 適用於 Java 的 SDK 2.0](https://github.com/aws/aws-sdk-java-v2) – 適用於 Java 程式設計語言的官方 AWS SDK。

請將這些程式庫新增至建置定義中，如下所示：

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

------

若要建立部署套件，請將函數程式碼和相依性編譯成單一 .zip 檔案或 Java 封存 (JAR) 檔案。針對 Gradle，[請使用`Zip`建置類型](#java-package-gradle)。針對 Apache Maven，[請使用 Maven Shade 外掛程式](#java-package-maven)。若要上傳部署套件，請使用 Lambda 主控台、Lambda API 或 AWS Serverless Application Model (AWS SAM)。

**注意**  
若要將您部署套件大小保持較小，請以階層方式將您的函式相依項目進行封裝。各層可讓您獨立管理相依項目，並可供多個函數使用，也可和其他帳戶共用。如需詳細資訊，請參閱[使用層管理 Lambda 相依項](chapter-layers.md)。

## 使用 Gradle 建立部署套件
<a name="java-package-gradle"></a>

若要在 Gradle 中建立具有函數程式碼和相依項的部署套件，請使用 `Zip` 建置類型。以下是[完整的範本 build.gradle 檔案](https://github.com/awsdocs/aws-lambda-developer-guide/blob/main/sample-apps/s3-java/build.gradle)的範例：

**Example build.gradle - 建置任務**  

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

此建置組態會在 `build/distributions` 目錄中產生部署套件。在 `into('lib')` 陳述式中，`jar` 任務會將包含主要類別的 JAR 封存檔組合至名稱為 `lib` 的資料夾中。此外，`configurations.runtimeClassPath` 任務會將相依項程式庫從建置的類別路徑複製到名稱為 `lib` 的資料夾中。

**Example build.gradle - 相依性**  

```
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 會以 Unicode 字母順序載入 JAR 檔案。如果 `lib` 目錄的多個 JAR 檔案包含相同類別，則會使用第一個 JAR。您可以使用以下 shell 指令碼來識別重複的類別︰

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

## 使用層來管理相依項
<a name="java-package-layers"></a>

您可以將函式的相依項封裝為層，使部署套件保持較小體積，獨立管理相依項。如需詳細資訊，請參閱[使用 Java Lambda 函數的層](java-layers.md)。

## 使用 Maven 建立部署套件
<a name="java-package-maven"></a>

要使用 Maven 建置部署套件，請使用 [Maven Shade 外掛程式](https://maven.apache.org/plugins/maven-shade-plugin/)。該外掛程式會建立一個 JAR 檔案，其中包含編譯的函數代碼及其所有相依性。

**Example pom.xml - 外掛程式組態**  

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

若要建置部署套件，請使用 `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] ------------------------------------------------------------------------
```

此命令會在 `target` 目錄中產生一個 JAR 檔案。

**注意**  
如果您正在使用[多版本 JAR (MRJAR)](https://openjdk.org/jeps/238)，則必須在 `lib` 目錄中包含 MRJAR (即由 Maven Shade 外掛程式產生的陰影 JAR)，並在將部署套件上傳到 Lambda 之前對其進行壓縮。否則，Lambda 可能無法正確解壓縮 JAR 檔案，導致您的 `MANIFEST.MF` 檔案被忽略。

如果您使用附加器程式庫 (`aws-lambda-java-log4j2`)，則還必須配置 Maven Shade 外掛程式的轉換器。轉換器程式庫會合併出現在附加器程式庫和 Log4j 中快取檔案的版本。

**Example pom.xml - 具備 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>
```

## 使用 Lambda 主控台上傳部署套件
<a name="java-package-console"></a>

 若要建立新函數，您必須先在主控台中建立函數，然後上傳您的 .zip 或 JAR 檔案。若要更新現有函數，請開啟函數的頁面，然後按照同樣的程序新增更新後的 .zip 或 JAR 檔案。

 如果您的部署套件檔案小於 50 MB，您可以透過直接從本機電腦上傳檔案來建立或更新函數。若 .zip 或 JAR 檔案大於 50 MB，您必須先將套件上傳至 Amazon S3 儲存貯體。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的說明 AWS 管理主控台，請參閱 [Amazon S3 入門](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html)。若要使用 上傳檔案 AWS CLI，請參閱*AWS CLI 《 使用者指南*》中的[移動物件](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

**注意**  
不能變更現有函數的[部署套件類型](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-PackageType) (.zip 或容器映像)。例如，您不能轉換容器映像函數以使用 .zip 封存檔。您必須建立新的函數。

**若要建立新的函數 (主控台)**

1. 開啟 Lambda 主控台的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)，然後選擇**建立函數**。

1. 選擇 **Author from scratch** (從頭開始撰寫)。

1. 在**基本資訊**下，請執行下列動作：

   1. 在**函數名稱**中輸入函數名稱。

   1. 在**執行期**中選取要使用的執行期。

   1. (選用) 在**架構**中選擇要用於函數的指令集架構。預設架構值為 x86\$164。請確定函數的 .zip 部署套件與您選取的指令集架構相容。

1. (選用) 在**許可**下，展開**變更預設執行角色**。您可建立新的**執行角色**，或使用現有的角色。

1. 選擇 **Create function (建立函數)**。Lambda 會使用您選擇的執行期建立一個基本的「Hello world」函數。

**若要從本機電腦上傳 .zip 或 JAR 封存檔 (主控台)**

1. 在 Lambda 主控台的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)中選擇要上傳 .zip 或 JAR 檔案的函數。

1. 選取**程式碼**索引標籤。

1. 在**程式碼來源**窗格中選擇**上傳來源**。

1. 選擇 **.zip 或 .jar 檔案**。

1. 若要上傳 .zip 或 JAR 檔案，請執行下列操作：

   1. 選取**上傳**，然後在檔案選擇器中選取您的 .zip 或 JAR 檔案。

   1. 選擇 **Open** (開啟)。

   1. 選擇**儲存**。

**若要從 Amazon S3 儲存貯體上傳 .zip 或 JAR 封存檔 (控制台)**

1. 在 Lambda 主控台的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)中選擇要上傳新 .zip 或 JAR 檔案的函數。

1. 選取**程式碼**索引標籤。

1. 在**程式碼來源**窗格中選擇**上傳來源**。

1. 選擇 **Amazon S3 位置**。

1. 貼上 .zip 檔案的 Amazon S3 連結 URL，然後選擇**儲存**。

## 使用 上傳部署套件 AWS CLI
<a name="java-package-cli"></a>

 您可以使用 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 建立新函數，或使用 .zip 或 JAR 檔案更新現有函數。使用 [create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) 和 [update-function-code](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) 命令來部署您的 .zip 或 JAR 套件。如果您的檔案小於 50 MB，則可以從本機建置電腦的檔案位置上傳套件。若檔案較大，則必須先從 Amazon S3 儲存貯體上傳 .zip 或 JAR 套件。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的指示 AWS CLI，請參閱*AWS CLI 《 使用者指南*》中的[移動物件](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

**注意**  
如果您使用 從 Amazon S3 儲存貯體上傳 .zip 或 JAR 檔案 AWS CLI，則儲存貯體必須與 AWS 區域 函數位於相同的 中。

 若要使用 .zip 或 JAR 檔案搭配 建立新的函數 AWS CLI，您必須指定下列項目：
+ 函數名稱 (`--function-name`)
+ 函數的執行期 (`--runtime`)
+ 函數[執行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)的 Amazon Resource Name (ARN) (`--role`)
+ 函數程式碼中處理常式方法的名稱 (`--handler`)

 您也必須指定 .zip 或 JAR 檔案的位置。如果您的 .zip 或 JAR 檔案位於本機建置電腦上的資料夾中，請使用 `--zip-file` 選項來指定檔案路徑，如下列範例命令所示。

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

 若要在 Amazon S3 儲存貯體中指定 .zip 檔案的位置，請使用如下列範例命令所示的 `--code` 選項。您只需針對版本控制的物件使用 `S3ObjectVersion` 參數。

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

 若要使用 CLI 更新現有函數，您可以使用 `--function-name` 參數指定函數的名稱。您也必須指定要用來更新函數程式碼的 .zip 檔案的位置。如果您的 .zip 檔案位於本機建置電腦上的資料夾中，請使用 `--zip-file` 選項來指定檔案路徑，如下列範例命令所示。

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

 若要在 Amazon S3 儲存貯體中指定 .zip 檔案的位置，請使用如下列範例命令所示的 `--s3-bucket` 和 `--s3-key` 選項。您只需針對版本控制的物件使用 `--s3-object-version` 參數。

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

## 使用 上傳部署套件 AWS SAM
<a name="java-package-cloudformation"></a>

您可以使用 AWS SAM 自動部署函數程式碼、組態和相依性。 AWS SAM 是 的延伸 CloudFormation ，提供定義無伺服器應用程式的簡化語法。下列範例範本會透過在 Gradle 使用的 `build/distributions` 目錄中的部署套件定義函數︰

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

若要建立函數，請使用 `package` 和 `deploy` 指令。這些命令是對 AWS CLI的自訂命令。它們會包裝其他命令，將部署套件上傳至 Amazon S3，使用物件 URI 重寫範本，並更新函數的程式碼。

下面的範例指令碼會執行 Gradle 建置並上傳到它建立的部署套件。它會在您第一次執行 CloudFormation 堆疊時建立堆疊。如果堆疊已存在，則指令碼會加以更新。

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

如需完整的工作範例，請參閱下列範例應用程式︰

**以 Java 編寫的範例 Lambda 應用程式**
+ [example-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/example-java) – Java 函式，示範如何使用 Lambda 處理訂單。此函數說明如何定義和還原序列化自訂輸入事件物件、使用 AWS SDK 和輸出記錄。
+ [java-basic](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-basic) - 具有單元測試和變數日誌組態的最小 Java 函數集合。
+ [java-events](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events) - Java 函數集合，其中包含如何處理來自各種服務 (例如 Amazon API Gateway、Amazon SQS 和 Amazon Kinesis) 事件的骨架程式碼。這些函數使用最新版 [aws-lambda-java-events](#java-package) 程式庫 (3.0.0 及更新版)。這些範例不需要 AWS SDK 做為相依性。
+ [s3-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/s3-java) - 一種 Java 函數，它處理來自 Amazon S3 的通知事件，並使用 Java Class Library (JCL) 以從上傳的映像檔案建立縮圖。
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java) – 此 Java 函式示範如何使用 Lambda 層，將相依項與核心函式程式碼分離封裝。