java11 使用ParameterizedTypeImpl 程序包sun.reflect.generics.reflectiveObjects不存在 maven编译失败

项目场景:

项目需要一个从接口获取数据集合的sdk,数据集合里面的元素类型会有多种,但是顶层的数据结构一样的,算是一种比较常见的使用方式:

{
	"total": 1234,
	"result":[
		{
			"name": "abc",
			"duty": "leader",
			"department": "IT"
		}
	]
}
public void getSomeData(){
        ResponseEntity<ApiResultDto<ElementApiResultDto>> responseEntity = restTemplate.exchange(
                API_URL + params,
                HttpMethod.GET,
                new HttpEntity<>(headersMap),
                getReference(ElementApiResultDto.class)
        );
}


    private <T> ParameterizedTypeReference<ApiResultDto<T>> getReference(Class<T> clazz) {
        ParameterizedTypeImpl type = ParameterizedTypeImpl.make(ApiResultDto.class, new Type[]{clazz}
                , ApiResultDto.class.getDeclaringClass());
        return ParameterizedTypeReference.forType(type);
    }

ParameterizedTypeImpl是java.lang.reflect.ParameterizedType参数化类型接口的一个实现,其在在这里的作用是将接口返回的集合数据正确反序列化成对应的类对象集合。


问题描述

上面的ParameterizedTypeImpl 类在java1.8正常使用,但是在java11会报找不到包:sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
编译时报:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project autumn-api: Compilation failure
[ERROR] /project/src/main/java/com/jimeng/lowcode/service/impl/AutoGenerateValueServiceImpl.java:[28,28] package sun.reflect.generics.reflectiveObjects is not visible
[ERROR]   (package sun.reflect.generics.reflectiveObjects is declared in module java.base, which does not export it to the unnamed module)

原因分析:

sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl是在rt.jar包里的,java9之后rt.jar被拆分成了不同的module,ParameterizedTypeImpl所在的module没有在默认导出的范围,所以会引用不到所在的包,导致编译失败,而且Oracle也想将ParameterizedTypeImpl在后面的版本删除。


解决方案:

本地临时解决方案

IDEA配置,将sun.reflect.generics.reflectiveObjects增加export,让项目内可以引用到。
这个方式在maven下依然会编译失败。
settings->Compiler->Java Compiler->override compiler parameters per-module:

-parameters --add-exports java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED

推荐的解决方案

选择使用其它的java.lang.reflect.ParameterizedType实现,比如(阿里巴巴fastjson.util或者谷歌guava里面apache里面都有其实现),不过其它团队的实现不一定有make方法的实现,这个时候使用构造函数构造一个ParameterizedTypeImpl也一样的。

    private <T> ParameterizedTypeReference<ApiResultDto<T>> getReference(Class<T> clazz) {
        ParameterizedTypeImpl parameterizedType = new ParameterizedTypeImpl( new Type[]{clazz}, ApiResultDto.class.getDeclaringClass(), ApiResultDto.class);
        return ParameterizedTypeReference.forType(parameterizedType);
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值