点击按钮发送FCM推送时抛出java.lang.SecurityException异常如何解决
问题排查与解决
这个异常和协程切换IO线程的逻辑没有关联,本质是高版本运行环境(Android API 33+、JDK 16+)下,代码尝试通过反射将java.lang.reflect.Method类的私有构造器设置为可访问,触发了系统的安全限制。
按以下优先级排查:
- 优先升级低版本依赖
90%以上的该场景异常由Retrofit、Gson、OkHttp版本过低导致。旧版本库内部在做JSON序列化、网络请求适配时,会尝试反射访问Method类的私有构造器,在高版本系统上直接被拦截。
把以下依赖升级到对应最低兼容版本即可修复:// 项目app模块build.gradle的dependencies块中 implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.okhttp3:okhttp:4.10.0' implementation 'com.google.code.gson:gson:2.10.1' - 修正FCM推送的实现逻辑
不要在Android客户端直接调用FCM服务端推送接口:FCM发送接口要求校验服务端密钥,硬编码在客户端会直接泄露凭证,属于严重安全漏洞。同时客户端直接调用FCM服务端时,很容易因为请求/响应数据结构定义不匹配,导致序列化库尝试反射解析系统类触发异常。正确做法是将推送发送逻辑部署到自有服务端,客户端仅请求自有服务端的业务接口触发推送。 - 打印完整异常栈定位具体触发点
你当前的catch代码只打印了异常类信息,拿不到具体触发的代码位置,修改异常捕获逻辑打印全栈:
复现异常后从日志的栈信息里,可以直接看到是哪段代码、哪个依赖触发了非法反射,针对性修复即可。catch (e: Exception){ Log.e(TAG, "send notification failed", e) } - 排查自定义反射逻辑
如果项目中自定义了Gson的TypeAdapter、或者用了其他反射工具类,检查代码中是否存在手动获取Method类构造器并调用setAccessible(true)的逻辑,这类访问系统非公开API的代码在高版本Android上必然触发异常,直接删除即可。
临时调试方案(禁止用于生产)
如果是在本地JVM环境调试接口触发该异常,可以给JVM添加启动参数临时放开反射限制:
--add-opens java.base/java.lang.reflect=ALL-UNNAMED
该参数仅对本地JVM生效,Android生产环境不支持这类配置,不能作为最终修复方案。
内容的提问来源于stack exchange,提问作者norengx
相关产品推荐
相关产品推荐

