如何解决 Java Lambda 函数中的“ClassNotFoundException”和“NoSuchMethodError”错误?

2 分钟阅读
0

当我尝试调用我的 Java AWS Lambda 函数时,我收到了“ClassNotFoundException”或“NoSuchMethodError”错误。如何解决这些错误?

简短描述

Java 运行时通过类的完全限定名称加载某个类但却找不到该类时,就会发生 ClassNotFoundException 错误。

**注意:**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。有关更多信息,请参阅 Retrieve a Lambda function

要从 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 存储桶源并且启用了存储桶版本控制时,才需要 Amazon S3 存储桶 URL。
  • 代码更改是在部署处理程序配置更改之前部署的。
    **注意:**Lambda 没有在一个原子更改中更新代码和配置的机制。

检查是否存在任何类文件问题

针对 ClassNotFoundException 错误中指定的类验证以下内容:

  • 它包含在部署包中。
    **注意:**如果找不到该类,那么在您创建部署包时,可能就未捆绑该类。
  • 其捆绑的类名与函数的处理程序值相同。
  • 它位于 /lib 或根目录中。
  • 如果将其引用为 Lambda 层,则其内容不会被提取到 java/lib 以外的目录中。
  • 它与函数打包的类的版本相同。如果类不是同一个版本,则请检查本地计算机的版本是否与您打包的版本不同。

检查是否存在任何 JAR 文件问题

确认您的函数是按预期在本地计算机上运行,还是从 AWS Serverless Application Model (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 插件

检查是否存在任何权限问题

Lambda 要求压缩包文件具有全局读取权限。有关更多信息,请参阅“我在上传 Lambda 部署包时遇到‘permission denied’或‘unable to import module’错误,如何进行问题排查?”

**重要提示:**在确定并修复问题后,必须手动捆绑并上传 Lambda 函数才能进行部署。然后,检查是否仍会收到错误。


相关信息

Java 中的 AWS Lambda 函数错误

在 AWS Lambda 中插入 Java 代码

在层中包含库依赖项

使用 AWS Lambda 函数的最佳实践

AWS 官方
AWS 官方已更新 2 年前