Skip to content

fix: exclude bridge methods from @JsonValue enum detection (#5127)#5128

Open
olsavmic wants to merge 1 commit intoswagger-api:masterfrom
olsavmic:fix/bridge-method-jsonvalue-enum
Open

fix: exclude bridge methods from @JsonValue enum detection (#5127)#5128
olsavmic wants to merge 1 commit intoswagger-api:masterfrom
olsavmic:fix/bridge-method-jsonvalue-enum

Conversation

@olsavmic
Copy link
Copy Markdown

Summary

Fixes #5127@JsonValue on an enum implementing a generic interface (e.g. PersistableEnum<String>) causes non-deterministic schema generation in OpenAPI 3.1 mode.

Root cause

When an enum implements a generic interface like PersistableEnum<T>, the Java compiler generates a bridge method Object getValue() alongside the real String getValue(). The compiler copies @JsonValue to the bridge method.

ReflectionUtils.getAnnotatedMethods() uses getDeclaredMethods() without filtering bridge methods, so both methods are returned. In ModelResolver._createSchemaForEnum(), findFirst() picks whichever getDeclaredMethods() returns first — which is unspecified per JVM spec.

  • If String getValue() wins → PrimitiveType.fromType(String.class) → schema with type: "string"
  • If Object getValue() (bridge) wins → PrimitiveType.fromType(Object.class)null → falls through to default

This causes non-deterministic output: the same code produces different schemas across JVM invocations (e.g. Maven Surefire vs IntelliJ test runner).

Fix

One-line change in ReflectionUtils.collectAnnotatedDeclaredMethods() to skip bridge methods:

if (!method.isBridge() && method.isAnnotationPresent(annotation)) {

Tests added

  • ReflectionUtilsTest.getAnnotatedMethods_excludesBridgeMethodsFromGenericInterface — verifies only the non-bridge method is returned
  • EnumPropertyTest.testJsonValueWithBridgeMethodFromGenericInterface — end-to-end: enum with generic interface gets correct type: "string" and enum values
  • New test model classes: PersistableEnum<T> interface and JacksonValueBridgeMethodEnum enum

…pi#5127)

When an enum implements a generic interface (e.g. PersistableEnum<String>),
the compiler generates a bridge method with @jsonvalue copied from the real
method. ReflectionUtils.getAnnotatedMethods() returned both, and findFirst()
in _createSchemaForEnum() picked whichever getDeclaredMethods() returned
first — which is non-deterministic per JVM spec. If the bridge method
(returning Object) was picked, PrimitiveType.fromType(Object.class) returned
null, causing the enum schema to lose its "type":"string" in OpenAPI 3.1 mode.

Filter bridge methods in collectAnnotatedDeclaredMethods() to ensure only
the real annotated method is found.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@JsonValue on enum with generic interface causes non-deterministic schema generation in OpenAPI 3.1

1 participant