AWS Lambda触发DynamoDB更新时出现ClassNotFoundException问题求助
我之前也踩过类似的坑,结合Lambda + DynamoDB触发场景下的常见问题,给你几个具体的排查方向,应该能帮你定位问题:
检查部署包的依赖完整性
这类类加载错误大概率是依赖没正确打包进去。如果用Gradle构建,确保你用了shadowJar任务来生成包含所有依赖的fat jar;如果是Maven,要配置maven-shade-plugin插件,把第三方依赖和自己的代码合并到一个jar里。要是手动上传zip包,别漏了把所有需要的第三方jar放进zip的根目录(Java项目不需要额外的lib目录,Lambda会自动加载根目录下的类文件)。确认运行时与依赖的版本兼容性
比如你Lambda配置的是Java 11运行时,但你的项目是用Java 17编译的,或者依赖包是基于更高JDK版本编译的,这会直接导致类加载失败。一定要保证项目编译的JDK版本和Lambda选择的运行时版本完全匹配。排查AWS SDK依赖冲突
Lambda的Java运行时已经内置了AWS SDK的部分版本(比如v1或v2),如果你自己打包了不同版本的SDK依赖,很容易出现类加载冲突,抛出NoClassDefFoundError。建议要么完全使用Lambda内置的SDK(不用在项目里重复引入),要么通过Lambda层来管理自定义版本的SDK,避免和内置版本冲突。查看CloudWatch的完整错误栈
别只看错误提示的开头,一定要找完整的错误栈,里面会明确指出找不到的具体类名。如果是你自己写的类,检查打包时有没有把对应的.class文件包含进去;如果是第三方类,确认依赖是否正确引入并打包。验证Lambda执行角色的基础权限
虽然这不是类加载错误的直接原因,但如果执行角色缺少dynamodb:DescribeStream、dynamodb:GetRecords等DynamoDB流权限,或者logs:PutLogEvents等日志权限,可能会导致触发失败或者错误日志不完整,干扰你的排查。先确认角色权限配置正确。
我自己之前遇到的情况是,用Maven默认的
package命令只打包了自己的代码,没包含第三方依赖,导致Lambda运行时找不到第三方类,换成maven-shade-plugin构建fat jar后问题就解决了。
内容的提问来源于stack exchange,提问作者Adnan Ali

