-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generics - recursive bound results in UnresolvedTypeVariable #88
Comments
CC @n1hility |
This bug blocks an improvement in the OptaPlanner quarkus extension to put it feature wise on par with the spring-boot starter. |
recursive types should be allowed, so I am calling this a bug. The unresolved type is for cases where you have undefined type parameters which at one point or another some bytecode frameworks were generating. |
Is there a workaround for this issue? |
@ge0ffrey the only workaround at the moment is to do this on the caller side by tracking identifiers. Sorry this one is taking longer for me to get to. There are some fundamental problems with implementing a solution that are tricky to get right. There are two major issues at play. The first is that we don't want to introduce a non-terminating hang (or stack overflow) for existing code out there that is currently expecting a finite scan. So we need to retrofit the API in some way to address that. The second issue is that the internals of jandex are designed to recycle instances for memory usage due to the amount of state involved (for example the exact same method signature, or generic type definition in multiple places in the index (different classes etc is reused via an intern pool). This requires immutable acyclic type nodes, and in the process of analysis these are rebuilt in a copy on write fashion. Altogether this makes it difficult to represent cyclical references and in a nice clean API. Solving this will likely involve some form of external cycle linkage table with unique identifiers (in a way that doesn't bloat memory) and probably a new Type like (e.g. CyclicTypeVariable) . |
Hello, is there an ETA on when this would likely be fixed? This issue is unfortunately blocking me right now and I'd need to know whether it's better to wait for a fix or to start searching for an alternative. EDIT: I avoided the issue by not having the class I rely on be discovered through CDI, but to specialize the class that injects it and hardcode it there instead. |
@Felk Glad you found a workaround. I am sorry for the long delay on this issue. It requires basically a rewrite of the generics handling, enforced inner class ordering, and additional APIs. Due to the garage scope I have prioritized the other items for 3.0. I will prioritize this for a 3.1 immediately after. |
Assigning to myself, as this is the last thing I wanna do for Jandex 3.0. |
I think I have a pretty decent implementation of this. It adds a new kind of type, a Implementation-wise, this requires a patching pass both when indexing a class (to resolve the unresolved type variables and propagate annotated type variables) and when deserializing an index (types are serialized in topological order, that is, if a type is composite, it is serialized after its constituent types, and references go against that), but nothing special. I'm currently finishing the work to support type annotations on mutually recursive type parameters, everything else is done, so hopefully next week. |
@Ladicek awesome, sounds like a good approach. Did you look at the interplay with type annotations? When those are applied they have to replace an immutable reference tree and this approach will conflict with cycles, switching to a reference type indirection as you are doing should solve it. |
The approach for type annotations I have is pretty sensible I think: for |
OK so type annotations on mutually recursive type parameters are quite a bit more complex than I imagined. Basically, when I have class Graph<G extends Graph<G, E, V>, E extends Edge<G, E, V>, V extends Vertex<G, E, V>> {
} then the bound of If I add type annotations to the type variable occurences, they are not propagated correctly to the "nested" type variables, because those are different instances. Which probably happens due to the copy-on-write mechanism of attaching type annotations to types. I'll need to spend more time on this. |
I believe I finally nailed it: #221 I want to do some tests with parameterized types that have an owner, but other than that, I think I'm done. Yay! |
Done in #221. |
If a class declares a recursive bound (which should be legal and often used e.g. in builders) such as
interface Score<S extends Score<S>> {}
the type hierarchy contains anUnresolvedTypeVariable
. And according to the javadoc "This type will only occur as a result of a bug, or a non-compliant Java class file".A test can be found here:
mkouba@2141db3
In fact, I'm not quite sure whether it's a bug or how to handle this correctly.
The text was updated successfully, but these errors were encountered: