java11 uses ParameterizedTypeImpl. The package sun.reflect.generics.reflectiveObjects does not exist. Maven compilation fails.

Project scenario:

The project requires an SDK that obtains a data collection from an interface. There are many types of elements in the data collection, but the top-level data structure is the same, which is a relatively common way of use:

{
    
    
	"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 is an implementation of the java.lang.reflect.ParameterizedType parameterized type interface. Its role here is to correctly deserialize the collection data returned by the interface into the corresponding collection of class objects.


Problem Description

The above ParameterizedTypeImpl class works normally in java1.8, but in java11 it will report that the package cannot be found: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
Compilation Times:

[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)

Cause Analysis:

sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl is in the rt.jar package. After java9, rt.jar was split into different modules. The module where ParameterizedTypeImpl is located is not in the default export range, so it will not be referenced. package, causing compilation to fail, and Oracle also wants to delete ParameterizedTypeImpl in later versions.


solution:

Local temporary solution

IDEA configuration, add sun.reflect.generics.reflectiveObjects to export so that it can be referenced in the project.
This method will still fail to compile under maven.
settings->Compiler->Java Compiler->override compiler parameters per-module:

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

Recommended solution

Choose to use other java.lang.reflect.ParameterizedTypeimplementations, such as (Alibaba fastjson.util or Google guava have their implementations in apache), but the implementations of other teams may not have the implementation of the make method. At this time, using the constructor to construct a ParameterizedTypeImpl is the same.

    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);
    }

Guess you like

Origin blog.csdn.net/wangxudongx/article/details/125628704