【电商项目】短信测试遇到的问题与解决方案:InaccessibleObjectException报错、单元测试通过但未接收到验证码

目录

一、InaccessibleObjectException报错

二、单元测试报错


一、InaccessibleObjectException报错

首先说一个尴尬的报错问题。

我在测试短信发送功能的时候后台报了这个错👇

**InaccessibleObjectException :**意思是代码(或第三方库)想通过反射偷偷访问 JDK 内部某个类或方法,但 Java 不让这么干,因为那个类没对你这边的模块开放访问权限。

对应到我的代码说人话就是:我发短信的那个代码抛了个异常,Dubbo 想把这个异常传回来,结果传的时候被 Java 拦住了,说"这个异常里面有我内部的东西,不让你看",然后 Dubbo 自己就崩了,真正的错误信息都看不到。

然后我去查了下造成的原因,网上常说的有这几种情况:

  1. JDK 版本太高(Java 9+ 引入了模块化系统,默认禁止反射访问 JDK 内部类)
  2. fastjson2 序列化 JDK 内部类(比如 ExecutionException)时被模块化拦截

解决方案基本都一样:加 JVM 启动参数 --add-opens java.base/java.util.concurrent=ALL-UNNAMED,手动开放访问权限。

本人很有自知之明啊,感觉自己弄不明白这个,问AI还容易被带偏,所以去求助老师了。

老师说,这可能是网关导致请求没转发到后端服务把 Dubbo 的请求转发丢了或者端口没通导致调用失败,让我先去检查 Higress 的端口映射有没有问题。结果发现端口确实有点问题。

Higress 容器内部的服务默认监听在 8080 端口,而不是 80。

我访问宿主机的 80 端口,Docker 帮我转给容器里的 8080 端口。

应该是80映射8080端口而不是80端口。 具体执行操作及结果如下**👇:**

复制代码
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE                                                                   COMMAND                  CREATED       STATUS       PORTS                                                                                                                                                                                                                 NAMES
f4b815f5775b   apacherocketmq/rocketmq-dashboard:latest                                "sh -c 'java $JAVA_O..."   2 days ago    Up 2 hours   0.0.0.0:8888->8082/tcp, [::]:8888->8082/tcp                                                                                                                                                                           rocketmq-dashboard
a32725f968e4   higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/all-in-one:2.2.3   "supervisord -c /etc..."   11 days ago   Up 2 hours   0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp, 0.0.0.0:8001->8001/tcp, [::]:8001->8001/tcp, 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp, 0.0.0.0:8443->8443/tcp, [::]:8443->8443/tcp   higress
[root@localhost ~]# docker stop a3
a3
[root@localhost ~]# cd /usr/local/higress/
[root@localhost higress]# docker run -d --rm --name higress-ai -v ${PWD}:/data \
     -p 8001:8001 -p 80:8080 -p 8443:8443  \
     higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/all-in-one:latest

1e224b2c4b67ea20b4acd874bc1dd755cee4c9824e7ad5cb1b51ac8b1cd69fc0
[root@localhost higress]# 

改完之后重新启动容器,但 Dubbo 调用还是报同样的错,所以问题不在这。

于是我又请师出山了。

老师远程检查了一番告诉我:

🤡弄了半天原来是这样。

InaccessibleObjectException 的前提是 Dubbo 在传一个异常,如果业务代码不抛异常,根本不会走到这一步。我应该把关注点放在"为什么会有异常"。再去看代码,我的 sendLoginCheckCode 方法调了短信接口,代码会去调短信接口,但测试环境没有营业执照发不出短信,就会抛异常,Dubbo 传异常时卡在了序列化那一步( Dubbo 要把短信发送失败的异常传回给调用方,但这个异常里包含了 JDK 内部的类,Java 9+ 的模块化机制不让序列化这种内部类,所以被拦住了),所以看到的是 InaccessibleObjectException,看不到真正的短信发送失败原因。

真是令人头大,下一个问题。

二、单元测试报错

把自己的手机号注册到阿里云短信测试白名单之后,单元测试发送短信报错。

这里主要就是强调一点注意:

  • 正常启动服务(main 方法启动):会加载 bootstrap.yml,连接 Nacos 拉配置。

  • JUnit 单元测试:不会自动触发 Nacos 配置加载逻辑 ,只会读取本地 application.yml。

  • 编写:

    aliyun:
    accessKeyId: 你的key
    accessKeySecret: 你的secret
    sms:
    signName: 你的签名
    templateCode: 你的模板code

我在弄完后,短信发送成功(代码不报错)但是收不到短信。然后想到了我之前给从阿里云复制的代码签名改了(我寻思测试就起个测试名)。改回来就好了。

不能随便在代码里改签名名字,代码写的签名必须是阿里云控制台【已经审核通过】的签名

然后我去逗我朋友玩,用他们的手机号测试,测试成功但验证码未收到。

isv.OUT_OF_SERVICE``Account suspended due to an insufficient balance.账号余额不足,账户被停用,短信服务暂停。

解决:给发送的号码添加到白名单五分钟后生效即可。

相关推荐
xiaoqiMikko43 分钟前
七条 advisory 各给了一个修复版,而一次修完的那个数字一条都没写
java·spring boot
气泡水好喝1 小时前
Java魔法探秘:从Java代码到CPU指令,一个方法调用的完整生命周期
java
气泡水好喝1 小时前
读《阿里巴巴Java开发手册》五年,这7条规约救了我太多次
java
凯哥Java1 小时前
System.setProperty 的正确姿势:Spring Boot 启动类里的“缺省值“魔法
java·spring boot·后端
lhldsg1 小时前
智慧场馆解决方案小程序系统:从架构设计到落地实践
java·小程序·需求分析
hfywmsj2 小时前
广州餐饮铺位招租的选址架构:流量入口与成本函数分析
java·大数据·jvm·广州餐饮铺位招租
爪哇岛国人2 小时前
原来我一直理解错了:实现接口真的必须实现所有方法吗?
java
万年咸鱼2 小时前
Java BufferedOutputStream 详解:原理、用法与性能优化
java·开发语言·性能优化
万年咸鱼2 小时前
Java BufferedInputStream 详解:原理、用法与实战
java·开发语言·python