Skip to content

Commit 80636e8

Browse files
authored
fix: exclude bridge methods from @jsonvalue enum detection (#5127) (#5128)
1 parent db9958e commit 80636e8

5 files changed

Lines changed: 73 additions & 1 deletion

File tree

modules/swagger-core/src/main/java/io/swagger/v3/core/util/ReflectionUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ private static void collectAnnotatedMethodsFromInterfaces(Class<?> type, Class<?
506506

507507
private static void collectAnnotatedDeclaredMethods(Class<?> cls, Class<? extends Annotation> annotation, List<Method> methods) {
508508
for (Method method : cls.getDeclaredMethods()) {
509-
if (method.isAnnotationPresent(annotation)) {
509+
if (!method.isBridge() && method.isAnnotationPresent(annotation)) {
510510
methods.add(method);
511511
}
512512
}

modules/swagger-core/src/test/java/io/swagger/v3/core/converting/EnumPropertyTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import io.swagger.v3.core.jackson.ModelResolver;
88
import io.swagger.v3.core.jackson.TypeNameResolver;
99
import io.swagger.v3.core.matchers.SerializationMatchers;
10+
import io.swagger.v3.core.oas.models.JacksonValueBridgeMethodEnum;
1011
import io.swagger.v3.core.oas.models.JacksonValueDefaultMethodEnum;
1112
import io.swagger.v3.core.oas.models.JacksonValuePrivateEnum;
1213
import io.swagger.v3.core.oas.models.Model1979;
@@ -266,4 +267,12 @@ public void testJsonValueOnInterfaceDefaultMethodIsRecognized() {
266267
assertEquals(schema.getType(), "string");
267268
assertEquals(schema.getEnum(), Arrays.asList("alpha", "beta", "gamma"));
268269
}
270+
271+
@Test(description = "it should handle @JsonValue on enum implementing generic interface with bridge method (issue #5127)")
272+
public void testJsonValueWithBridgeMethodFromGenericInterface() {
273+
final Schema schema = context.resolve(new AnnotatedType(JacksonValueBridgeMethodEnum.class));
274+
assertNotNull(schema);
275+
assertEquals(schema.getType(), "string");
276+
assertEquals(schema.getEnum(), Arrays.asList("created", "in_progress", "confirmed"));
277+
}
269278
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package io.swagger.v3.core.oas.models;
2+
3+
import com.fasterxml.jackson.annotation.JsonValue;
4+
5+
/**
6+
* Enum implementing a generic interface, causing the compiler to generate a bridge
7+
* method {@code Object getValue()} alongside the real {@code String getValue()}.
8+
* The {@code @JsonValue} annotation is present on the real method, but the compiler
9+
* may copy it to the bridge method as well. This tests that the bridge method does
10+
* not interfere with schema type detection.
11+
*
12+
* @see <a href="https://github.com/swagger-api/swagger-core/issues/5127">Issue #5127</a>
13+
*/
14+
public enum JacksonValueBridgeMethodEnum implements PersistableEnum<String> {
15+
CREATED("created"),
16+
IN_PROGRESS("in_progress"),
17+
CONFIRMED("confirmed");
18+
19+
private final String value;
20+
21+
JacksonValueBridgeMethodEnum(String value) {
22+
this.value = value;
23+
}
24+
25+
@JsonValue
26+
@Override
27+
public String getValue() {
28+
return value;
29+
}
30+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.swagger.v3.core.oas.models;
2+
3+
/**
4+
* Generic interface whose {@code getValue()} method causes the compiler to generate
5+
* a bridge method on implementing enums. Used to test that bridge methods do not
6+
* interfere with {@code @JsonValue} detection.
7+
*/
8+
public interface PersistableEnum<T> {
9+
T getValue();
10+
}

modules/swagger-core/src/test/java/io/swagger/v3/core/util/reflection/ReflectionUtilsTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,31 @@ public void getAnnotatedMethods_findsDefaultMethodAnnotationFromInterface() {
222222
assertEquals(methods.get(0).getName(), "toValue");
223223
}
224224

225+
@Test
226+
public void getAnnotatedMethods_excludesBridgeMethodsFromGenericInterface() {
227+
// GenericValueEnum implements PersistableEnum<String> which causes the compiler
228+
// to generate a bridge method Object getValue() alongside String getValue().
229+
// Both may carry @JsonValue, but only the non-bridge method should be returned.
230+
List<Method> methods = ReflectionUtils.getAnnotatedMethods(GenericValueEnum.class, JsonValue.class);
231+
assertEquals(methods.size(), 1, "should find exactly one @JsonValue method (excluding bridge)");
232+
assertEquals(methods.get(0).getReturnType(), String.class, "should find the String-returning method, not the Object bridge");
233+
}
234+
225235
// --- Support classes for getAnnotatedMethods tests ---
226236

237+
private interface GenericPersistableEnum<T> {
238+
T getValue();
239+
}
240+
241+
private enum GenericValueEnum implements GenericPersistableEnum<String> {
242+
A("alpha"), B("beta");
243+
private final String value;
244+
GenericValueEnum(String value) { this.value = value; }
245+
@JsonValue
246+
@Override
247+
public String getValue() { return value; }
248+
}
249+
227250
private static class SuperclassWithJsonValue {
228251
@JsonValue
229252
public String getJsonValue() { return "super"; }

0 commit comments

Comments
 (0)