Java Lambda 関数からの「ClassNotFoundException」エラーおよび「NoSuchMethodError」エラーのトラブルシューティング方法を教えてください。

所要時間2分
0

AWS Lambda 関数を呼び出そうとすると、「ClassNotFoundException」エラーまたは「NoSuchMethodError」エラーが発生します。これらのエラーを解決するにはどうすればよいですか?

簡単な説明

ClassNotFoundException エラーは、Java ランタイムが完全修飾名でクラスをロードしても、クラスを検索しない場合に発生します。

注: Java の完全修飾クラス名には、クラスのデプロイパッケージとクラス名が含まれます。

NoSuchMethodError エラーは、参照する依存関係バージョンがパッケージバージョンと異なる場合に発生します。

Java Lambda 関数デプロイパッケージ構造の詳細については、「Deploy Java Lambda functions with .zip or JAR file archives」を参照してください。

解決策

注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、使用している AWS CLI が最新バージョンであることを確認してください

Lambda 関数のデプロイパッケージをダウンロードする

Lambda 関数のデプロイパッケージのファイル構造を表示するには、下記のいずれかを実行します。

zipinfo コマンドを実行して関数のデプロイパッケージをダウンロードする場合

次の zipinfo コマンドを実行します。

重要: my-deployment-package.zip は、使用するデプロイパッケージのファイル名に置き換えてください。次のコマンドは、Linux、Unix、および macOS オペレーティングシステムでのみ有効です。

$ zipinfo my-deployment-package.zip

Lambda get-function AWS CLI コマンドを実行して関数のデプロイパッケージをダウンロードする場合

次の get-function コマンドを実行します。

重要: my-function は、使用する Lambda 関数の名前に置き換えてください。

aws lambda get-function \
    --function-name  my-function

コマンド出力には、ファイルのダウンロードに使用できる署名付き URL が表示されます。詳細については、「Lambda 関数の取得」を参照してください。

Lambda コンソールから関数のデプロイパッケージをダウンロードする場合

1.    Lambda コンソールの [関数] ページで関数を選択します。

2.    [アクション] を選択します。

3.    [関数のエクスポート] を選択します。

4.    [関数のエクスポート] ダイアログボックスで、[デプロイパッケージのダウンロード] を選択します。

関数ハンドラーメソッド名を確認する

詳細については、「AWS Lambda function handler in Java」を参照してください。

CI/CD パイプラインの問題を確認する

継続的インテグレーションと継続的デリバリー (CI/CD) パイプラインを使用して関数をパッケージ化してデプロイする場合は、以下について検証します。

  • 必要な依存関係はすべて、関数をパッケージ化する時にバンドルされている。
  • 参照される依存関係バージョンがすべて正しい。
  • 必要な Amazon Simple Storage Service (Amazon S3) バケット URL が存在し、ファイルの最新バージョンを指している。
    注: Amazon S3 バケット URL は、Amazon S3 バケットソースを使用していて、バケットのバージョニングが有効になっている場合にのみ必要です。
  • ハンドラー設定の変更をデプロイする前に、コードの変更がデプロイ済みである。
    注: Lambda には、1 つのアトミック変更でコードと設定を更新するメカニズムはありません。

クラスファイルの問題を確認する

ClassNotFoundException エラーで指定されたクラスについて、以下を検証します。

  • デプロイパッケージに含まれている。
    注: クラスが見つからない場合は、デプロイパッケージを作成した際にバンドルされていない可能性があります。
  • バンドルされたクラス名が、関数のハンドラー値と同じである。
  • /lib またはルートディレクトリに置かれている。
  • Lambda レイヤーとして参照される場合、その内容が java/lib 以外のディレクトリに抽出されていない。
  • 関数にパッケージされているクラスと同じバージョンである。クラスが同じバージョンでない場合、パッケージしたものと異なるバージョンがローカルマシンにあるかを確認します。

JAR ファイルの問題を確認する

関数がローカルマシン、または AWS サーバーレスアプリケーションモデル (AWS SAM)で正常に実行されるかどうかを確認します。Lambda から呼び出されたときにのみ関数が失敗する場合は、参照される依存関係 (JAR ファイル) に問題がある可能性があります。

ヒント: Eclipse 統合開発環境 (IDE) を使用して Java Lambda 関数を構築することを検討してください。Eclipse で利用可能なプラグインを使ってプロジェクトを作成すると、自動的にプロジェクトが適切なビルド用に設定されます。詳細については、「Using Lambda with the AWS Toolkit for Eclipse」を参照してください。

ローカルディレクトリに存在し、Java CLASSPATH 環境変数で指定されている JAR ファイルについて、以下を検証します。

  • ファイルが関数のデプロイパッケージに含まれている。
    注: 参照されている JAR ファイルが見つからない場合は、デプロイパッケージの作成時にバンドルされていない可能性があります。
  • ファイルバージョンが、デプロイパッケージ内のファイルと同じである。

ファイルが見つからない場合や、バージョンが正しくない場合は、すべての依存関係 (JAR ファイル) を /lib またはルートディレクトリにコピーします。正しいバージョンを参照していることを確認してください。その後に、圧縮したコンテンツをアップロードします。

注: Apache Maven や Gradle などのビルドツールを使用している場合は、デプロイアーティファクトのビルド時に必要なプラグインを使用してください。例えば、Apache Maven Shade Plugin などです。

権限の問題を確認する

Lambda では、zip パッケージファイルにグローバルな読み取り権限が付与される必要があります。詳細については、「Lambda デプロイパッケージをアップロードする際に表示される「アクセス許可が拒否されました」と「unable to import module」というエラーを解決するにはどうすればよいですか?」を参照してください。

重要: 問題を特定して修正したら、Lambda 関数を手動でバンドルしてアップロードしてデプロイする必要があります。次に、引き続きエラーが発生するかどうかを確認します。


関連情報

AWS Lambda function errors in Java

Instrumenting Java code in AWS Lambda

Including library dependencies in a Layer

Best practices for working with AWS Lambda functions

AWS公式
AWS公式更新しました 2年前
コメントはありません