

# .zip または JAR ファイルアーカイブで Java Lambda 関数をデプロイする
<a name="java-package"></a>

AWS Lambda 関数のコードは、スクリプトまたはコンパイルされたプログラム、さらにそれらの依存関係で構成されます。*デプロイパッケージ*を使用して、Lambda に関数コードをデプロイします。Lambda は、コンテナイメージと .zip ファイルアーカイブの 2 種類のデプロイパッケージをサポートしています。

このページでは、デプロイパッケージを .zip ファイルまたは Jar ファイルとして作成し、そのデプロイパッケージを使用して、AWS Lambda (AWS Command Line Interface) で関数コードを AWS CLI にデプロイする方法について説明します。

**重要**  
Java 25 では Ahead-of-Time (AOT) キャッシュのサポートが導入されました。Lambda がマネージドランタイムを更新するとキャッシュが予期しない動作を引き起こす可能性があるため、関数を .zip または JAR ファイルアーカイブとしてデプロイするときは AOT キャッシュを使用しないことを強くお勧めします。詳細については、「[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 は、コマンドラインシェルでコマンドを使用して 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) － 現在の呼び出しのリクエスト ID を[関数ログ](java-logging.md)に追加するために使用できる Apache Log4j 2 のアペンダーライブラリ。
+ [AWS SDK for Java 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>
```

------

デプロイパッケージを作成するには、関数コードと依存関係を 1 つの ZIP ファイルまたは Java Archive (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 ファイルが使用されます。重複するクラスを識別するには、次のシェルスクリプトを使用します。

**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 未満の場合は、ローカルマシンから直接ファイルをアップロードして関数を作成または更新できます。50 MB を超える .zip または JAR ファイルの場合は、まず Amazon S3 バケットにパッケージをアップロードする必要があります。AWS マネジメントコンソール を使用して Amazon S3 バケットにファイルをアップロードする手順については、「[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. **[一から作成]** を選択します。

1. **[基本的な情報]** で、以下を行います。

   1. **[関数名]** に、関数名を入力します。

   1. **[ランタイム]** で、使用するランタイムを選択します。

   1. (オプション) **[アーキテクチャ]**で、関数の命令セットアーキテクチャを選択します。デフォルトのアーキテクチャは x86\$164 です。関数用の .zip デプロイパッケージと選択した命令セットのアーキテクチャに互換性があることを確認してください。

1. (オプション) **[アクセス権限]** で、**[デフォルトの実行ロールの変更]** を展開します。新しい **[実行ロール]** を作成することも、既存のロールを使用することもできます。

1. **[関数の作成]**を選択します。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. **[開く]** をクリックします。

   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 パッケージをアップロードする必要があります。AWS CLI を使用して Amazon S3 バケットにファイルをアップロードする方法については、「AWS CLI ユーザーガイド」の「[オブジェクトの移動](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)」を参照してください。

**注記**  
AWS CLI を使用して Amazon S3 バケットから .zip または JAR ファイルをアップロードする場合、このバケットは関数と同じ AWS リージョン に配置する必要があります。

 AWS CLI を含む .zip または JAR ファイルを使用して新しい関数を作成するには、以下を指定する必要があります。
+ 関数の名前 (`--function-name`)
+ 関数のランタイム (`--runtime`)
+ 関数の[実行ロール](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html) (`--role`) の Amazon リソースネーム (ARN)
+ 関数コード内のハンドラーメソッド (`--handler`) の名前

 .zip ファイルの場所も指定する必要があります。.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) – Lambda を使用して注文処理を行う Java 関数。この関数は、カスタム入力イベントオブジェクトの定義と逆シリアル化、 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) - Amazon API Gateway、Amazon SQS、Amazon Kinesis などのさまざまなサービスからのイベントを処理する方法のスケルトンコードを含む Java 関数のコレクション。これらの関数は、最新バージョンの [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) － Amazon S3 からの通知イベントを処理し、Java Class Library (JCL) を使用して、アップロードされたイメージファイルからサムネイルを作成する Java 関数。
+ [layer-java](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-java) – Lambda レイヤーを使用して、コアとなる関数コードから分離して依存関係をパッケージ化する方法を示す Java 関数。