最近在动手搭建一个项目,把自己遇到的问题记录一下
问题
碰到一个奇葩的问题,在一个模块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解决这个问题。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。