使用SAM部署Java Serverless应用至AWS Lambda遇ClassNotFoundException
这种情况大概率是SAM打包流程或者模板配置出了问题——毕竟手动上传jar能正常运行,说明你的代码本身没问题,只是SAM生成的部署包不符合Lambda的加载要求。下面是几个常见的排查方向和解决办法:
1. 检查SAM模板中的Handler配置是否完整
Lambda对Java handler的格式要求是**包名.类名::方法名**,比如你的场景应该是helloworld.App::handleRequest(假设你的处理方法叫handleRequest)。
打开你的template.yaml,找到Function资源的Handler字段,确认是不是只写了helloworld.App(仅指定类名,缺少方法名)。如果是,修改为完整的handler路径:
Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: Handler: helloworld.App::handleRequest # 其他配置项...
2. 确认SAM的构建方法匹配你的项目类型
如果你的项目用Maven管理,要确保template.yaml里的Metadata配置正确指定了构建工具:
Resources: HelloWorldFunction: Type: AWS::Serverless::Function Metadata: BuildMethod: maven # 其他配置项...
如果是Gradle项目,就把BuildMethod改成gradle。这个配置告诉SAM用正确的工具编译打包你的代码,要是配置错了,SAM可能不会正确处理你的类文件。
3. 检查SAM生成的部署包内容
手动下载S3存储桶里SAM上传的部署包,解压后查看是否存在helloworld/App.class文件:
- 如果找不到这个文件,说明SAM构建时没把编译后的类包含进去。你可以本地执行
sam build,然后去.aws-sam/build/HelloWorldFunction目录下查看生成的文件结构,确认你的类是否在里面。 - 对于Maven项目,SAM默认会执行
mvn package,如果本地build后的目录里也没有你的类,检查pom.xml配置:- 确认
maven-compiler-plugin配置正确,编译后的类输出到target/classes目录; - 确认
maven-shade-plugin或maven-assembly-plugin(如果使用的话)配置正确,确保生成的jar包含你的类和依赖。
- 确认
4. 对比手动上传jar与SAM生成jar的结构差异
用命令分别列出两个jar的内容,对比结构差异:
# 列出手动上传的jar内容 jar tf your-manual-upload.jar # 列出SAM生成的jar内容 jar tf sam-generated.jar
比如如果你的手动jar里helloworld/文件夹直接在根目录,而SAM生成的jar里把它放在BOOT-INF/classes/下面(比如Spring Boot项目的可执行jar结构),Lambda就会找不到类——因为Lambda默认从jar根目录加载类,这种情况你需要调整项目打包方式,生成符合Lambda要求的普通fat jar(比如用maven-shade-plugin替代Spring Boot的打包插件)。
5. 查看SAM构建日志找异常
本地执行sam build时,仔细查看输出日志,有没有编译失败、文件复制失败的警告或错误。比如Maven编译报错会导致类文件没生成,SAM自然没法打包进去。
内容的提问来源于stack exchange,提问作者Sunny

