spring-projects / spring-projects/spring-framework

`ResolvableType.resolveType()` functionality is useful but package-private

Open
#36,103 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: core status: waiting-for-triage
Dominant language
Java
Stars
60.2k
Forks
38.8k
Avg merge
5d 2h
Merged PRs (30d)
27

Description

Hi Spring team!

I've come across a snag/deficiency with ResolvableType and resolving type variables and I do have a workaround, but I'm sharing anyway:


Suppose I have a class with a generic (in a library)

class Thing<T> { }

and I expect this to be subclassed with a generic

 static class Thingy<T> extends Thing<T> {};

and then given a concrete type in usage

interface MyService {
  Thingy<List<String>> method();
}

The library wants to find the generic in terms of Thing on the method's return value, so I tried

thingGeneric = ( returnType = ResolvableType.forType(method.getGenericReturnType()) ).as(Thing.class).getGeneric(0);

which does represent List<String> (according to the .toString() on the result), but the "raw class" from that expression is null and the getType() result is useless TypeVariable without context. Meanwhile returnType.resolveGeneric(0) correctly returns List.class but that loses the <String> generic.

In the debugger, thingGeneric.resolveType().getType() produces the List<String> Type, but resolveType() is package protected with a note about how the intermediate value wouldn't be Serializable (personally I couldn't care less about that, and there are other methods that have notes about non-serializable resolvable type methods that are not package protected).

My workaround is (expecting that client usage looks like the above),... to take both the returnType.getGeneric(0) (first generic of the method type) and returnType.as(Thing.class).getGeneric(0) (the T passed to Thing<T>) and sanity check that they are both .isAssignableFrom() each other, and then use returnType.getGeneric(0).getType() which does resolve.

I'm wondering if it's possible to either make resolveType() public or add something like this for this case?

   public Type getResolvedGenericType(int index) { return getGeneric(i).resolveType().getType(); }

Thanks in advance!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in spring-core/src/main/java/org/springframework/core/ResolvableType.java, especially resolveType() and the note around lines 914-919, then trace getGeneric() and resolveGeneric() for the reported Thing case. Done means the requested resolved generic Type information is usable through an appropriate public API while addressing the stated serialization concern.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.