调用Ec2ClientBuilder.build时遇NoSuchFieldError:IDENTITY_PROVIDERS问题
解决AWS SDK 2.x创建Ec2Client时的NoSuchFieldError: IDENTITY_PROVIDERS错误
问题场景
我尝试通过以下代码创建Ec2Client:
AwsCredentials awsCredentials = AwsBasicCredentials.create("<ACCESS_KEY>", "<SECRET_ACCESS_KEY>"); AwsCredentialsProvider awsCredentialsProvider = StaticCredentialsProvider.create(awsCredentials); Ec2Client ec2Client = Ec2ClientBuilder.credentialsProviders(awsCredentialsProvider).region(Region.of("ap-south-1")).build;
运行时抛出错误:
Method threw 'java.lang.NoSuchFieldError' exception.
具体原因为:
java.lang.NoSuchFieldError: IDENTITY_PROVIDERS
栈跟踪片段:
software.amazon.awssdk.services.ec2.DefaultEc2BaseClientBuilder.finalizeServiceConfiguration(DefaultEc2BaseClientBuilder.java:80) software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder.finalizeChildConfiguration(AwsDefaultClientBuilder.java:181) software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.syncClientConfiguration(SdkDefaultClientBuilder.java:181) software.amazon.awssdk.services.ec2.DefaultEc2ClientBuilder.buildClient(DefaultEc2ClientBuilder.java:36) software.amazon.awssdk.services.ec2.DefaultEc2ClientBuilder.buildClient(DefaultEc2ClientBuilder.java:25) software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.build(SdkDefaultClientBuilder.java:148) ... (内部类未展示)
环境与依赖信息
- JAVA SDK 8
- AWS SDK 2.22.9(所有AWS依赖统一版本)
- Spring Boot 2.7.7
- Gradle 7.3.3
Gradle依赖配置:
awsSdkVersion = "2.22.9" ... aws = [ ec2 = "software.amazon.awssdk:ec2:" + awsSdkVersion, sqs = "software.amazon.awssdk:sqs:" + awsSdkVersion, ... ]
通过implementation aws.ec2引入依赖。
特殊现象:应用启动时通过静态LoadingCache(Guava)执行相同代码创建Ec2Client无报错,但动态创建时触发上述错误。
排查方向与解决方案
深度检查依赖冲突
- 即使指定了统一的AWS SDK版本,Spring Boot或其他第三方依赖仍可能引入不同版本的AWS SDK核心包。执行
gradle dependencies命令,查找所有software.amazon.awssdk:*相关依赖,确认是否存在版本不一致的情况,重点检查core、aws-core这类基础包。 - 若发现冲突,在Gradle中通过
resolutionStrategy强制统一版本:configurations.all { resolutionStrategy { force "software.amazon.awssdk:core:${awsSdkVersion}" force "software.amazon.awssdk:aws-core:${awsSdkVersion}" force "software.amazon.awssdk:ec2:${awsSdkVersion}" } }
- 即使指定了统一的AWS SDK版本,Spring Boot或其他第三方依赖仍可能引入不同版本的AWS SDK核心包。执行
类加载器问题排查
- 静态创建与动态创建的类加载器可能不同:静态LoadingCache由系统类加载器加载,而动态创建可能使用Spring上下文类加载器等子容器类加载器,导致加载了不同版本的AWS SDK类。
- 在创建Ec2Client前后打印类加载器信息对比:
System.out.println("Current ClassLoader: " + Thread.currentThread().getContextClassLoader()); System.out.println("Ec2ClientBuilder ClassLoader: " + Ec2ClientBuilder.class.getClassLoader()); - 若类加载器不一致,尝试在动态创建时强制使用系统类加载器:
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader()); // 执行创建Ec2Client的代码 } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); }
修正AWS SDK构建代码
- 代码中存在两处错误:
build是方法需加括号build();Ec2ClientBuilder的正确方法是单数credentialsProvider,而非复数credentialsProviders(复数用于添加多个凭证提供者,易引发配置异常)。修正后代码:Ec2Client ec2Client = Ec2ClientBuilder.credentialsProvider(awsCredentialsProvider) .region(Region.of("ap-south-1")) .build();
- 代码中存在两处错误:
清理构建缓存
- 执行
gradle clean build清理本地构建缓存,避免旧版本类文件残留。同时清理IDE缓存(如IntelliJ通过File -> Invalidate Caches / Restart操作)。
- 执行
内容的提问来源于stack exchange,提问作者Nishant Joshi
相关产品推荐
相关产品推荐

