.zip または JAR ファイルアーカイブで Java Lambda 関数をデプロイする - AWS Lambda

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

.zip または JAR ファイルアーカイブで Java Lambda 関数をデプロイする

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

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

前提条件

AWS CLI は、コマンドラインシェルでコマンドを使用して AWS サービスとやり取りするためのオープンソースツールです。このセクションの手順を完了するには、以下が必要です。

ツールとライブラリ

Lambda には、Java 関数用に以下のライブラリが用意されています。

  • com.amazonaws:aws-lambda-java-core (必須) - ランタイムがハンドラーに渡すハンドラーメソッドインターフェイスとコンテキストオブジェクトを定義します。独自の入力タイプを定義する場合、これが唯一必要なライブラリです。

  • com.amazonaws:aws-lambda-java-events – Lambda 関数を呼び出す のサービスからのイベントの入力タイプ。

  • com.amazonaws:aws-lambda-java-log4j2 – 現在の呼び出しのリクエスト ID を関数ログ に追加するために使用できる Apache Log4j 2 のアペンダーライブラリ。

  • AWS SDK for Java 2.0 - Java プログラミング言語用の公式の AWS SDK。

これらのライブラリは Maven Central Repository から入手できます。以下のようにそれらのライブラリをビルド定義に追加します。

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 ビルドタイプを使用します。Apache Maven の場合、Maven Shade プラグインを使用します。デプロイパッケージをアップロードするには、Lambda コンソール、Lambda API、AWS Serverless Application Model (AWS SAM) を使用します。

注記

デプロイパッケージのサイズを小さく保つため、関数の依存関係をレイヤーにパッケージ化します。レイヤーを使用すると、依存関係を独立して管理し、複数の関数で使用できます。また、他のアカウントと共有することもできます。詳細については、「Lambda レイヤーでの作業」を参照してください。

Gradle を使用したデプロイパッケージのビルド

関数のコードおよび Gradle の依存関係を含むデプロイパッケージを作成するには、Zip 構築タイプを使用します。「完全なサンプル build.gradle ファイル」の例を示します。

例 build.gradle - ビルドタスク
task buildZip(type: Zip) { into('lib') { from(jar) from(configurations.runtimeClasspath) } }

このビルド設定により、build/distributions ディレクトリにデプロイパッケージが作成されます。into('lib') ステートメント内で、jar タスクはメインクラスを含む jar アーカイブを lib という名前のフォルダにアセンブルします。さらに、configurations.runtimeClassPath タスクが、依存関係ライブラリをビルドのクラスパスから同じ lib フォルダにコピーします。

例 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 ファイルが使用されます。重複するクラスを識別するには、次のシェルスクリプトを使用します。

例 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

依存関係の Java レイヤーを作成する

注記

Java のようなコンパイル済み言語の関数でレイヤーを使用しても、Python のようなインタープリター言語と同じメリットが得られない場合があります。Java はコンパイル済み言語なので、関数は初期化フェーズで共有アセンブリを手動でメモリに読み込む必要があり、コールドスタート時間が長くなる可能性があります。代わりに、コンパイル時にすべての共有コードを含めて、組み込みコンパイラ最適化機能を活用することをお勧めします。

このセクションでは、依存関係をレイヤーに含める方法について説明します。依存関係をデプロイパッケージに含める方法については、「Gradle を使用したデプロイパッケージのビルド」または「Maven を使用したデプロイパッケージのビルド」を参照してください。

関数にレイヤーを追加すると、Lambda はレイヤーのコンテンツをその実行環境の /opt ディレクトリに読み込みます。Lambda ランタイムごとに、PATH 変数には /opt ディレクトリ内の特定のフォルダパスがあらかじめ含まれます。レイヤーのコンテンツが PATH 変数によって確実に取得されるようにするには、次のフォルダパスにコンテンツを含めます。

  • java/lib (CLASSPATH)

例えば、レイヤーの.zip ファイルの構造は次のようになります。

jackson.zip └ java/lib/jackson-core-2.2.3.jar

さらに、Lambda は /opt/lib ディレクトリ内のライブラリ、および /opt/bin ディレクトリ内のバイナリを自動的に検出します。Lambda がレイヤーのコンテンツを正しく検出できるように、次の構造でレイヤーを作成することもできます。

custom-layer.zip └ lib | lib_1 | lib_2 └ bin | bin_1 | bin_2

レイヤーをパッケージ化したら、「Lambda でのレイヤーの作成と削除」および「関数へのレイヤーの追加」を参照してレイヤーの設定を完了してください。

Maven を使用したデプロイパッケージのビルド

Maven でデプロイパッケージをビルドするには、Maven Shade プラグインを使用します。このプラグインは、コンパイルされた関数コードとそのすべての依存関係を含む JAR ファイルを作成します。

例 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)」を使用している場合、を lib ディレクトリに MRJAR (つまり、Maven Shade プラグインによって生成されるシェーディング JAR) 含め、デプロイパッケージを Lambda にアップロードする前に圧縮する必要があります。そうしないと、Lambda が JAR ファイルを適切に解凍せず、MANIFEST.MF ファイルが無視される可能性があります。

アペンダーライブラリ (aws-lambda-java-log4j2) を使用する場合は、Maven Shade プラグインのトランスフォーマーも設定する必要があります。トランスフォーマーライブラリは、アペンダーライブラリと Log4j の両方のキャッシュファイルのバージョンを組み合わせます。

例 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 コンソールでデプロイパッケージのアップロード

新しい関数を作成するには、まずコンソールで関数を作成し、次に .zip または JAR ファイルをアップロードする必要があります。既存の関数を更新するには、その関数のページを開き、同じ手順に従って更新した .zip または JAR ファイルを追加します。

デプロイパッケージファイルが 50 MB 未満の場合は、ローカルマシンから直接ファイルをアップロードして関数を作成または更新できます。50 MB を超える .zip または JAR ファイルの場合は、まず Amazon S3 バケットにパッケージをアップロードする必要があります。AWS Management Console を使用して Amazon S3 バケットにファイルをアップロードする手順については、「Amazon S3 の開始方法」を参照してください。AWS CLI を使用してファイルをアップロードするには、「AWS CLI ユーザーガイド」の「オブジェクトの移動」を参照してください。

注記

既存の関数のデプロイパッケージタイプ (.zip またはコンテナイメージ) を変更することはできません。例えば、コンテナイメージ関数を変換して .zip ファイルアーカイブを使用することはできません。この場合は、新しい関数を作成する必要があります。

新しい関数を作成するには (コンソール)
  1. Lambda コンソールの [関数] ページを開き、[関数の作成] を選択します。

  2. [一から作成] を選択します。

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

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

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

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

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

  5. [関数の作成]を選択します。Lambda は、選択したランタイムを使用して基本的な「Hello world」関数を作成します。

ローカルマシンから .zip または JAR アーカイブをアップロードするには (コンソール)
  1. Lambda コンソールの [関数ページ] で、.zip または JAR ファイルをアップロードする関数を選択します。

  2. [コード] タブを選択します。

  3. [コードソース] ペインで、[アップロード] をクリックします。

  4. .zip または.jar ファイルを選択します。

  5. .zip または JAR ファイルをアップロードするには、次の操作を行います。

    1. [アップロード] をクリックし、ファイルセレクターで .zip または JAR ファイルを選択します。

    2. [開く] をクリックします。

    3. [保存] をクリックします。

Amazon S3 バケットから .zip または JAR アーカイブをアップロードするには (コンソール)
  1. Lambda コンソールの [関数ページ] で、新しい .zip または JAR ファイルをアップロードする関数を選択します。

  2. [コード] タブを選択します。

  3. [コードソース] ペインで、[アップロード元] をクリックします。

  4. [Amazon S3 ロケーション] を選択します。

  5. .zip ファイルの Amazon S3 リンク URL を貼り付けて、[保存] をクリックします。

AWS CLI を使用したデプロイパッケージのアップロード

AWS CLI を使用して新しい関数を作成したり、.zip または JAR ファイルを使用して既存の関数を更新したりできます。create-function コマンドと update-function-code コマンドを使用して、.zip または JAR パッケージをデプロイします。ファイルが 50 MB 未満の場合は、ローカルビルドマシン上のファイルの場所からパッケージをアップロードできます。サイズの大きいファイルの場合は、Amazon S3 バケットから .zip または JAR パッケージをアップロードする必要があります。AWS CLI を使用して Amazon S3 バケットにファイルをアップロードする方法については、「AWS CLI ユーザーガイド」の「オブジェクトの移動」を参照してください。

注記

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

AWS CLI を含む .zip または JAR ファイルを使用して新しい関数を作成するには、以下を指定する必要があります。

  • 関数の名前 (--function-name)

  • 関数のランタイム (--runtime)

  • 関数の実行ロール (--role) の Amazon リソースネーム (ARN)

  • 関数コード内のハンドラーメソッド (--handler) の名前

.zip ファイルの場所も指定する必要があります。.zip または JAR ファイルがローカルビルドマシン上のフォルダにある場合は、次のコマンド例に示すように、--zip-file オプションを使用してファイルパスを指定します。

aws lambda create-function --function-name myFunction \ --runtime java21 --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 java21 --handler example.handler \ --role arn:aws:iam::123456789012:role/service-role/my-lambda-role \ --code S3Bucket=myBucketName,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 myBucketName --s3-key myFileName.zip --s3-object-version myObject Version

AWS SAM によるデプロイパッケージのアップロード

AWS SAM を使用して、関数コード、設定、依存関係のデプロイを自動化できます。AWS SAM は AWS CloudFormation の拡張であり、サーバーレスアプリケーションを定義するための構文が簡略化されています。以下のサンプルテンプレートは、Gradle 用の build/distributions ディレクトリにあるデプロイパッケージを使用する関数を定義します。

例 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 Properties: CodeUri: build/distributions/java-basic.zip Handler: example.Handler Runtime: java21 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 ビルドを実行し、作成されたデプロイパッケージをアップロードします。また、初回実行時に AWS CloudFormation スタックを作成します。そのスタックがすでに存在する場合は更新します。

例 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 アプリケーション
  • [java17-examples] — Java レコードを使用して入力イベントデータオブジェクトを表現する方法を示す Java 関数。

  • java-basic - 単位テストと変数ログ記録設定を使用する、最小限の Java 関数のコレクション。

  • java-events - Amazon API Gateway、Amazon SQS、Amazon Kinesis などのさまざまなサービスからのイベントを処理する方法のスケルトンコードを含む Java 関数のコレクション。これらの関数は、最新バージョンのaws-lambda-java-eventsライブラリ (3.0.0 以降) を使用します。これらの例では、依存関係としての AWS SDK が不要です。

  • s3-java - Amazon S3 からの通知イベントを処理し、Java Class Library (JCL) を使用して、アップロードされたイメージファイルからサムネイルを作成する Java 関数。

  • API Gateway を使用して Lambda 関数を呼び出す - 従業員情報を含む Amazon DynamoDB テーブルをスキャンする Java 関数。次に、Amazon Simple Notification Service を使用して、仕事の記念日を祝うテキストメッセージを従業員に送信します。この例では、API ゲートウェイを使用して関数を呼び出します。