It's incredible that it doesn't work. Is it a bug or a feature that nobody have implemented in Spring Framework?

It's the base of Generics principle (Below, I propose a solution to solve it after creation object you have the type so inject after construction object Type as private and final in object as Class).

I have a generics class where S is a request body and T is response body of a webclient in a reactive mode get new Bearer Token or return latest token, if it doens't expried, and calling server by that token without using .block*() methods in no blocking mode.

In my class I need to use my class which is Client and a method return T type responsebody and pass requestbody parameter as S type but using T in below and it doesn't work:

public Mono<T> getResponse( @NotBlank String logHash,
                @NotBlank String url,
                @NotNull @NotBlank @NotEmpty S requestBody,
                @NotNull @NotBlank @NotEmpty Class<T> responseBodyClass) {

    return getToken()
       .flatMap(token -> 
            webClient
            .post()
            .uri(url)
            .header("Authorization", "Bearer " + token)
            .body(BodyInserters.fromValue(requestBody))
            .retrieve()
            .onStatus(HttpStatus.INTERNAL_SERVER_ERROR::equals, response -> response.bodyToMono(String.class).map(Exception::new))
            .onStatus(HttpStatus.BAD_REQUEST::equals, response -> response.bodyToMono(String.class).map(Exception::new))
THE PROBLEM ! ========> .bodyToMono(new ParameterizedTypeReference<T>() {})
            .doOnSuccess(response -> log.debug("{} full url {} response {}", logHash, this.serverUrl + url, response))
            .doOnError(ex -> {
                    log.error("{} {}", logHash, ex.getMessage());
                    ex.printStackTrace();
            })
       )
       .doOnSuccess(token -> log.debug("{} url {} response {}", logHash, this.serverUrl + url, token))
       .doOnError(ex -> {
            log.error("{} {}", logHash, ex.getMessage());
            ex.printStackTrace();
       });

I need to substitute in previous code this line (It's incredible because type must be part of this bean customized dinamically by Spring Framework AOP in the code, I think that a SOLUTION for AOP Spring Framework is add a final object Class in proxied class and in runtime substitute T with correct class passed in constructor by @Autowired annotation as private final value not only verify type class on return this avoid this type of exception because object will have S and T type not only on return methods of Generics class):

.bodyToMono(new ParameterizedTypeReference<T>() {})

with responseBody Class Type which is a .class of my responseBody to avoid exception because JVM can't find T type for return body object:

.bodyToMono(responseBody) What type of Generics Type is this implementatio?I autowire class I pass Type in autowiring how is possibile that this can't find Type?

new ParameterizedTypeReference<T>() {}

caller without use @Autowired as best practices:

private Client<CheckCustomerBody, ApimResponse> client = null;

And in method that use client it I need to passawhen call it

        client = new Client<CheckCustomerBody, ApimResponse>();
        client.configure(   WebClient.builder(),
                ClientType.XXXX_XX,
                channelEnum,
                logHash,
                Optional.empty(),
                Optional.empty(),
                Optional.empty()
            );
    return client
        .getResponse(   logHash,
                WebOrderConstants.API_EXT_CHECK,
                request,
                ApimResponse.class)
        .map(apimResponse -> validationProductChange(
                                            apimResponse.getResponse(),
                        customer.getClientAccountCode(),
                            logHash
                     )
                    ? "OK"
                    : "KO"
        )
        .doOnError(ex -> {
                log.error("{} END {} : Error using d365 service", logHash, prefix);
                ex.printStackTrace();
        });

Thanks a lot for your reply, I searched a different solution but I can't find it and I don't know why this is normal in AOP of Spring, have Type in Generics class can find a lot of exceptions.

Please analyze this scenario but in general will be very usefull allow to inject by Spring Framework AOP the type of Generics when object is created to analyze in runtime if there are errors and without add type strictly in class.

Spring Team can use the same logic of @Value used for application.properties but in runtime you have Type when istantiate the class or using @PostConstruct.

Comment From: skyblackhawk

Interesting article for JVM where Java not allow but AOP allow it so will be interesting implement it

Comment From: sdeleuze

Please provide a minimal reproducer as an attached project or a link to a repository with a test that allow to reproduce the error and a as concise and focused formulation of you question and/or expected behavior.

Comment From: skyblackhawk

Ok, it depends on the kind of type erasure in Generics for backwards compatibility with the 20 year old JVM. Community don't ask the JVM team why they can't think that via the configuration on the JVM it is possible to specify a new parameter when Java is in runtime that links Types used in Generics only adding in runtime specific metadata class to original class Generics metadata and inject that type in that object in realtime, so that of the real object have type in the post construct by AOP AspectJ for example? Java continue to ensure backwards compatibility checks at compile time whether the code allows this new mode, i.e. the generics continue to work as before or add an olderVersions parameter, for example to work in type erasure mode or with types in generics by a parameter. So that JVM will haven't heap pollution and support the right type in class in compilation and execution with a Generics class, metadata class added and verify in compile and runtime that's all correct by type without pass parameter to return from a method if it must used in Generic method for example Jackson in my example. If olderVersion parameter is enabled remove follow mechanism and for default support it: - that add in runtime metadata Class in memory and - add after post construct the return type Class

that is the problem in Generics to specify by an adder parameter Class<>.

I know that Generics = Object but in a method of Generics you need to know what real type using because it can be passed to another class method that need to know how map data in it as Jackson.

I know now for what reason you reply me in that mode ;)

Comment From: sdeleuze

Please pay attention to my ask in https://github.com/spring-projects/spring-framework/issues/34583#issuecomment-2720542619, and provide a minimal reproducer as an attached project or a link to a repository.

Comment From: skyblackhawk

I close it without JDK Community that change eraser type no solution can be found... Please read previous comment I replied alone finding the problem. Only collections based on a object can use new ParameterizedTypeReference() {} to avoid duplicate of classes in memory heap this increase performance of Heap memory but creation pollution of heap memory.

Because Generics are managed as Object and without Class metadata you can't do nothing. It exists for JDK backward compatibility to first version.

So if JDK community not implement a solution by a flag on JDK JRE no solution can be found, the smart solution by AspectJ 1.9.23 for Java23 or Spring Framework 6 AOP can't be followed.