Apple M1芯片Mac本地运行Java GAE标准应用时Cloud Firestore API无响应
本地M1芯片Mac上Firebase Admin SDK调用Cloud Firestore永久Pending问题
问题基础信息
Java后端应用部署在App Engine环境运行完全正常,但在本地环境启动时,所有Cloud Firestore的调用都会始终处于pending待处理状态,无法收到服务端响应。该异常仅在搭载Apple M1芯片的MacBook Air上出现,同版本代码在Windows环境本地运行无任何异常。
运行环境
- 应用类型:基于Jersey 2.29开发的Java 8 REST Web服务,通过Maven构建
- 开发IDE:IntelliJ IDEA 社区版2021.1,本地运行流程参照GCP官方IntelliJ本地部署指引
- 本地系统:M1芯片MacBook Air,运行macOS Big Sur 11.2.3
可复现的现象
- 本地运行时直连线上正式Cloud Firestore服务,未使用本地Firestore模拟器
- 同一段Firestore调用代码直接放到独立main方法中运行,可正常完成请求、拿到响应
- 核心业务代码流程:
// 创建集合引用 CollectionReference collectionReference = FirestoreClient.getFirestore().collection(getCollectionPath()); // 基于集合创建查询 DocumentReference documentReference = collectionReference.document(id); ApiFuture<DocumentSnapshot> future = documentReference.get(); DocumentSnapshot documentSnapshot = future.get();
- 如果为异步调用设置超时阈值,会抛出明确的超时异常:
DocumentSnapshot documentSnapshot = future.get(TIMEOUT, TIME_UNIT);
java.util.concurrent.TimeoutException: Waited 30000 milliseconds (plus 6 milliseconds delay) for com.google.api.core.AbstractApiFuture$InternalSettableFuture@627262b5[status=PENDING]
根因与修复方案
问题核心根因
该异常源于M1芯片arm64架构下,Firebase Admin SDK底层依赖的gRPC网络层原生库加载失效:
- 旧版本Firebase Admin SDK默认绑定的grpc-java版本低于1.45.0,未内置适配macOS aarch64(M1架构)的原生网络二进制文件
- 类加载上下文的差异导致加载失败被静默吞掉:独立main方法运行时使用系统类加载器,可借助Rosetta转译正常加载x86_64版本的gRPC原生库;但Jersey嵌入式Web服务运行时的自定义类加载器加载原生库时,不会抛出明确的链接错误,只会让底层gRPC连接一直卡在初始化阶段,最终表现为接口返回的ApiFuture永久处于pending状态。
可落地的修复操作
- 方案一:升级gRPC依赖版本
在Maven的pom.xml中手动引入1.46.0及以上版本的grpc-net依赖,覆盖Firebase Admin SDK自带的旧版本依赖,确保SDK能正常加载适配M1 arm64的原生库:<dependency> <groupId>io.grpc</groupId> <artifactId>grpc-net</artifactId> <version>1.46.0</version> </dependency> - 方案二:添加启动VM参数修正架构识别
本地应用的IntelliJ运行配置中,添加以下VM参数,强制gRPC匹配正确的原生库路径:-Dio.grpc.netty.shaded.io.netty.nativework.override=true -Dos.arch=aarch_64 - 方案三:临时验证用的快速修复
如果不想调整依赖版本,可右键IntelliJ IDEA的应用图标,选择「显示简介」,勾选「使用Rosetta打开」后重启IDE再运行应用。此时Java进程会以x86_64模式通过Rosetta转译运行,gRPC原生库可正常加载,不会再出现请求永久pending的问题。
内容的提问来源于stack exchange,提问作者Luyi
相关产品推荐
相关产品推荐

