Skip to content

Search for JsonValue in all classes and interfaces#4770

Merged
ewaostrowska merged 2 commits intoswagger-api:masterfrom
T3rm1:fix-jsonvalue
Apr 8, 2026
Merged

Search for JsonValue in all classes and interfaces#4770
ewaostrowska merged 2 commits intoswagger-api:masterfrom
T3rm1:fix-jsonvalue

Conversation

@T3rm1
Copy link
Copy Markdown
Contributor

@T3rm1 T3rm1 commented Oct 25, 2024

This PR fixes a regression introduced by issue #3998, which added support for @JsonValue on enum fields and private methods. That fix only searched getDeclaredMethods() on the enum class itself, breaking a valid Jackson pattern where @JsonValue is declared on an interface the enum implements.


What was broken

When an enum implements an interface that carries @JsonValue, swagger-core failed to find the annotation and fell back to raw enum constant names instead of the serialized values.

Case 1 — @JsonValue on an abstract interface method:

public interface InterfaceWithJacksonValue {
    @JsonValue
    int getJsonValue();
}

public enum JacksonValueInInterfaceEnum implements InterfaceWithJacksonValue {
    TEN(10);
    @Override public int getJsonValue() { return jsonValue; }
}
// Before: schema enum was ["TEN"]
// After:  schema enum is  [10]       ✓

Case 2 — @JsonValue on an interface default method (overridden without repeating the annotation):

public interface InterfaceWithDefaultJsonValue {
    @JsonValue
    default String toValue() { return "default"; }
}

public enum JacksonValueDefaultMethodEnum implements InterfaceWithDefaultJsonValue {
    ALPHA, BETA, GAMMA;
    @Override public String toValue() { return name().toLowerCase(); }
}
// Before: schema enum was ["ALPHA", "BETA", "GAMMA"]
// After:  schema enum is  ["alpha", "beta", "gamma"]  ✓

What changed

ModelResolver.java — The @JsonValue method lookup was changed from a one-class scan:

// Before
Arrays.stream(enumClass.getDeclaredMethods())
    .filter(m -> m.isAnnotationPresent(JsonValue.class))
    .filter(m -> m.getAnnotation(JsonValue.class).value())
    .findFirst();

to a full hierarchy scan using the new utility:

// After
ReflectionUtils.getAnnotatedMethods(enumClass, JsonValue.class).stream()
    .findFirst();

ReflectionUtils.java — New public method getAnnotatedMethods(Class<?> type, Class<? extends Annotation> annotation) that walks:

  1. The class itself and all superclasses (up to but excluding Object)
  2. All directly implemented interfaces, and their parent interfaces, recursively

The duplicate inner loop pattern was also refactored into a shared private helper collectAnnotatedDeclaredMethods.


@T3rm1 notes that the same gap exists for fields in inherited classes (not just methods), but intentionally defers that to a separate PR.

@MichakrawSB
Copy link
Copy Markdown

Thank you for your contribution! ❤️
We’re closing this PR as part of our ongoing cleanup of long-standing and inactive items.

Due to its age, we’re unable to review or merge it reliably.
If the change is still important, feel free to open a fresh PR and reference this one so we can evaluate it with full, updated context.

Thanks again for supporting the Swagger ecosystem!

@MichakrawSB MichakrawSB closed this Mar 8, 2026
@T3rm1
Copy link
Copy Markdown
Contributor Author

T3rm1 commented Mar 8, 2026

What? Are you serious? This is an easy change. You didn't even try to merge it, did you?
It also has tests so it's simple to verify it's working.

@MichakrawSB
Copy link
Copy Markdown

Hi @T3rm1,

Sorry about this. We're doing a general cleanup to avoid very old PRs staying open for so long. I assumed this PR was no longer relevant since the linked issue was already closed.

If you're still waiting on this to be merged, I will reopen the PR.
A fresh issue with updated context would also help us review it faster.
Thanks!

@MichakrawSB MichakrawSB reopened this Mar 8, 2026
@T3rm1
Copy link
Copy Markdown
Contributor Author

T3rm1 commented Mar 8, 2026

This fixes a bug that was introduced by the issue that was closed. I think this is still relevant.

@T3rm1
Copy link
Copy Markdown
Contributor Author

T3rm1 commented Mar 9, 2026

@MichakrawSB I rebased on master. Please add it to the backlog.

@ewaostrowska ewaostrowska merged commit 383a6cf into swagger-api:master Apr 8, 2026
7 checks passed
@ewaostrowska
Copy link
Copy Markdown
Contributor

Thank you @T3rm1 for handling this regression. This is great! I have only added few more test cases and refactored the code slightly

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.

3 participants