同一代码在不同Idea版本差异下报错踩坑

一、背景

    最近和小伙伴们合伙做一个自己的项目,处于功能模块迭代中;

    后端代码基于Ruoyi进行的魔改,代码框架基本已经稳定了,而且测试环境运行OK;

    spring boot版本: 2.7.15

    springfox-boot-starter: 3.0.0 (包含swagger2、swagger-ui)

    mapstruct: 1.5.3.Final

二、遇到问题

    周六上午,有个小伙伴说他的本地项目启动时候报错了(必现问题),报错堆栈信息如下:

    java.lang.NoClassDefFoundError: org/mapstruct/factory/Mappers

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestParameterMapperImpl' defined in URL 
[jar:file:/D:/repo/io/springfox/springfox-swagger2/3.0.0/springfox-swagger2-3.0.0.jar!/springfox/documentation/swagger2/mappers/RequestParameterMapperImpl.class]: 
Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: 
Failed to instantiate [springfox.documentation.swagger2.mappers.RequestParameterMapperImpl]: 
Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/mapstruct/factory/Mappers
....省略......
Caused by: java.lang.NoClassDefFoundError: org/mapstruct/factory/Mappers
    at springfox.documentation.swagger2.mappers.RequestParameterMapper.<init>(RequestParameterMapper.java:45)
    at springfox.documentation.swagger2.mappers.RequestParameterMapperImpl.<init>(RequestParameterMapperImpl.java:13)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211)
    ... 24 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.mapstruct.factory.Mappers
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

三、问题定位

    跟他确认过,本地没做其他配置修改,只是拉下来正常开发功能;

    怀疑过旧编译class,进行过mavn clean,报错依旧;

    确认了JDK版本,maven仓库中springfox-swagger2-3.0.0.jar大小,也一致;

    理论上,不太应该呀;完全一样的代码,我本地没问题,他那边必现;

    去度娘、google搜了一下,在github上有个类似issue:https://github.com/springfox/springfox/issues/3635

    issue中遇到相同问题的人不少,并未找到有用的解决方案, 就CLOSE; 也看了的MapStruct的FAQ;

    重新梳理了一下项目的pom文件,发现之前将mapstruct的scope为provided;

<!-- mapstruct -->
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <scope>provided</scope>
</dependency> 

MapStruct有多种component model;

默认:需要在runtime时,引用mapstruct;即scope应该为compile;

其它(spring\jsr330等):scope可以为provided;

注意:使用spring boot maven plugin时,即使mapstruct的scope为provided,最终应用jar中也会包含mapstruct;

    那么,发现一个可能,mapstruct就算配置provided,package时spring boot maven plugin也会把包打进来;但是在idea运行时,机制是不一样, idea版本不同,可能不一定会把包打进来;

    我本地idea console如下:

    查看本地idea运行临时jar,在MANIFEST.MF的Class-Path中,我这边可以搜索到mapstruct;另外一个小伙伴,则搜不到;

    比对了idea版本,IntelliJ IDEA 2022.3 是OK的,IntelliJ IDEA 2021.3 有问题;

    实锤了,不同idea版本针对mapstruct的处理机制不同;

    小伙伴把他本地idea版本更新为2023.3最新版本,运行OK;

四、解决方案

    从项目代码上来说,我们使用mapstruct的Default Component Model,而springfox-swagger2则使用了Default、Spring两种Model,需要在运行时依赖mapstruct;

    将mapstruct的scope调整为compile(默认scope),成功解决。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值