使用AWS SDK for Java v2创建S3桶抛出NoClassDefFoundError异常
问题根因
该异常属于典型的AWS Java SDK v2 依赖冲突/依赖缺失问题,和贴出的S3操作代码逻辑、桶权限、区域配置没有任何关系。
报错中提示找不到的software/amazon/awssdk/protocols/query/internal/unmarshall/AwsXmlErrorUnmarshaller类属于AWS SDK的protocols-query模块,SDK版本迭代过程中,原本在xml协议模块下的错误反序列化类被拆分到query协议模块中,出现以下任意一种情况就会触发该报错:
- 项目中引入的多个AWS SDK子模块版本不一致,比如s3模块版本较高,但核心协议相关模块版本过低,低版本模块中不存在该类
- 依赖传递过程中
protocols-query包被其他依赖排除,运行时类加载器找不到对应类 - 手动引入s3依赖时没有正确引入关联的传递依赖
排查步骤
- 统一核查项目中所有
software.amazon.awssdkgroupId下的依赖版本,确认是否存在版本号不一致的情况 - 查看项目依赖树,确认是否存在
protocols-query包,是否被其他依赖规则排除:- Maven环境执行命令:
mvn dependency:tree | findstr "software.amazon.awssdk"(Windows系统)或mvn dependency:tree | grep "software.amazon.awssdk"(类Unix系统) - Gradle环境执行命令:
./gradlew dependencies | grep "software.amazon.awssdk"
- Maven环境执行命令:
- 检查是否存在其他第三方依赖引入了低版本AWS SDK组件,覆盖了项目中配置的高版本
修复方案
推荐使用AWS官方提供的BOM(物料清单)统一管理所有SDK组件版本,从根源上避免版本不一致问题:
- Maven项目配置方式:
先在pom.xml的dependencyManagement节点中引入BOM,指定要使用的SDK版本(建议选择正式发布的稳定版本):
<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.25.0</version> <!-- 可替换为任意正式稳定版,所有SDK模块版本会自动和该值对齐 --> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
之后引入s3模块时不需要再指定版本号,BOM会自动关联所有同版本的必要依赖:
<dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> </dependency> </dependencies>
- Gradle项目配置方式:
在build.gradle中引入BOM后再添加s3依赖即可,同样不需要单独指定s3版本:
dependencies { implementation platform('software.amazon.awssdk:bom:2.25.0') // 可替换为任意正式稳定版,所有SDK模块版本会自动和该值对齐 implementation 'software.amazon.awssdk:s3' }
如果暂时不想调整为BOM管理方式,也可以手动修复:
- 把所有
software.amazon.awssdk下的依赖版本统一为同一个值 - 手动添加和其他SDK模块同版本的
protocols-query依赖 - 清理项目编译缓存,重新拉取依赖后启动即可:Maven执行
mvn clean compile,Gradle执行./gradlew clean build
内容的提问来源于stack exchange,提问作者Nitin Alety
相关产品推荐
相关产品推荐

