踩坑reflections反射库突然无法通过反射正常加载类,原因竟是Guava未做新老版本兼容。

背景

我的代码没有变动,测试突然找过来,说一个接口无法正常运行了。通过报错发现是一个工具类无法通过反射加载类。

问题描述:

其他同学负责的分支并入了测试环境后,测试反映我的接口调用出现反射问题【reflections依赖版本覆盖导致reflections反射出错】。

关键代码,仅仅是下述伪代码的样子:

1
Util.check();

报错:

1
2
3
4
5
6
java.lang.NoSuchMethodError: com.google.common.collect.Sets$SetView.iterator()Lcom/google/common/collect/UnmodifiableIterator;

        at org.reflections.Reflections.expandSuperTypes(Reflections.java:380)
        at org.reflections.Reflections.<init>(Reflections.java:126)
        at org.reflections.Reflections.<init>(Reflections.java:168)
        at org.reflections.Reflections.<init>(Reflections.java:141)   

问题分析:

可以看到是 Util 初始化动作使用了 reflections 进行反射操作。

同时,可以看到我们的工程中有多个 Reflection 版本,如图:

我们工程中有多个reflections依赖版本

查找reflection github仓库issue,发现已有该问题反馈:https://github.com/ronmam o/reflections/issues/194 。

可看到原因是 Guava 新旧版本不兼容导致的问题。

问题解决:【二选一即可】

  1. 找到出现问题的reflection版本源,将其exclude掉。此处我们使用
1
mvn dependency:tree

打印maven依赖树,如图,我们可以看到是哪个module依赖了不同的reflections包: 工程下的reflections依赖树

由于前期测试使用0.9.9-RC1版本是不出错的,我们本次将0.9.11版本exclude掉,如图: 找到引入的gav,将reflections排除掉

  1. 明确指定Guava版本,避免此处的版本不兼容。
1
2
3
4
5
6
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.0-jre</version>
    <scope>compile</scope>
</dependency>