最近在动手搭建一个项目,把自己遇到的问题记录一下

问题

碰到一个奇葩的问题,在一个模块order-domain里面使用了mapstruct,创建一个Mapper接口,但是生成的实现类没有字段映射,如下图:

mapstruct生成的实现类,只new了一个对象,没有字段映射:

项目模块依赖关系: order-infra -> order-domain -> order-api

排查

然后我猜测了各种可能的问题,
1)最开始我以为是版本兼容的问题,把mapstruct版本调低,没有解决
2)然后网上找了一下,说是maven-compiler-plugin的问题,我有专门导入了maven-compiler-plugin插件,也没有解决问题。
3)又有说是字段类型等不匹配的问题,我把字段直接复制过去,一样没有解决问题
4)然后我又怀疑是jdk版本问题,我用的jdk18,调低了jdk版本,还是没有解决
5)接着我又以为是项目里多余的依赖冲突导致,移除了多余的依赖,还是没有解决问题
6)clean 重编译的无数遍就行不行

最后我发现,在另外一个模块order-infra的mapstruct接口实现类是有字段映射的,我仔细比较了一下两个模块pom文件,发现order-infra里面有lombok的导入,order-domain里面没有lombok导入。但是order-domain依赖的order-api,order-api是有导入lombok的。我抱着死马当活马医的想法,把order-infra里面的lombok依赖复制到order-domain里面,重试了一下,竟然奇迹般的好了

问题分析

我发现order-infra里的lombok依赖带有<optional>true</optional>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

这个是什么意思呢?

在 Maven 中,optional 属性用于控制依赖项是否被认为是可选的。当一个依赖被标记为 optional 时,这意味着它不会被自动传递给项目的下游依赖。换句话说,如果你有一个项目 A 依赖于项目 B,而项目 B 依赖于项目 C,那么只有当项目 A 显式要求项目 C 时,项目 C 才会被包含在内。

看一下我们之前的依赖关系:

order-infra ------依赖----->order-domain -----依赖--->order-api
显式依赖lombok optional没有显式依赖lombok显式依赖lombok 不是optional

如果我去掉order-infra的optional,那么domain里面mapstruct生成的实现类就是正常的。但是如果我加上order-infra的optional,那么domain里面mapstruct生成的实现类就是没有字段映射的。

这里让人费解,按照optional的逻辑,order-domain显示依赖了order-api,order-api显式依赖的lombok且不是optional的,那么order-domain不需要显式依赖lombok,也可以包含。不应该受到order-infra的影响。

结论

我还没搞明白怎么回事?

解决

经过多次测试返现,问题表现不稳定,order-domain不显式依赖lombok,有时候也可以正常生成实现类,有时候又不行。所以决定在order-domain里面显式依赖lombok解决这个问题。


杜若
70 声望3 粉丝

引用和评论

0 条评论