Skip to content

Commit

Permalink
Fix GenericType resolution in parameterized classes
Browse files Browse the repository at this point in the history
Port the code from geantryref.TypeToken#extractType for classes passed
into GenericType.

Fixes jdbi#2305
  • Loading branch information
hgschmie committed Mar 24, 2023
1 parent 118c1cc commit a53d152
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Unreleased

- fix `GenericType` creation in parameterized classes (#2305)
- add `SqlStatements#setAttachAllStatementsForCleanup`. Setting this configuration flag will attach all created statements to their handles for resource cleanup. Default is `false`. (#2293, thanks @jodastephen)
- add `SqlStatements#setAttachCallbackStatementsForCleanup`. Setting this configuration flag will attach all created statements within one of the `Jdbi` callback methods to the handle. This allows code that uses the `Jdbi` callback methods to delegate resource management fully to Jdbi. This flag is set by default. (#2293, thanks @jodastephen)
- fix problem when using the jdbi bom in spring projects (#2295, thanks @jedvardsson)
Expand Down
15 changes: 15 additions & 0 deletions core/src/main/java/org/jdbi/v3/core/generic/GenericTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*/
package org.jdbi.v3.core.generic;

import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
Expand Down Expand Up @@ -100,7 +102,20 @@ public static Optional<Type> findGenericParameter(Type type, Class<?> parameteri
* @return the parameter on the supertype, if it is concretely defined.
* @throws ArrayIndexOutOfBoundsException if n &gt; the number of type variables the type has
*/
@SuppressWarnings("PMD.AvoidDeeplyNestedIfStmts")
public static Optional<Type> findGenericParameter(Type type, Class<?> parameterizedSupertype, int n) {
if (type instanceof Class) {
// this is the same code as TypeToken#extractType
AnnotatedType t = ((Class) type).getAnnotatedSuperclass();
if (t instanceof AnnotatedParameterizedType) {
AnnotatedParameterizedType pt = (AnnotatedParameterizedType) t;
if (((ParameterizedType) pt.getType()).getRawType() == parameterizedSupertype) {
return Optional.ofNullable(pt.getAnnotatedActualTypeArguments()[n]).map(AnnotatedType::getType);
}
}
}

// fall back to the type reflector
return Optional.ofNullable(GenericTypeReflector.getTypeParameter(type, parameterizedSupertype.getTypeParameters()[n]));
}

Expand Down
12 changes: 12 additions & 0 deletions core/src/test/java/org/jdbi/v3/core/generic/GenericTypesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package org.jdbi.v3.core.generic;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Optional;

import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -77,6 +78,17 @@ public void findMultipleGenericParameters() throws NoSuchMethodException {
.contains(Void.class);
}

@Test
void testGenericTypeWorksInParameterizedClasses() {
class Foo<T> {
Type getType() {
return new GenericType<List<String>>() {}.getType();
}
}

assertThat(new Foo<>().getType()).isNotNull();
}

@Test
public void resolveType() throws NoSuchMethodException {
abstract class A<T> {
Expand Down

0 comments on commit a53d152

Please sign in to comment.