Visitar URL original
Enum aliases from an appended `AnnotationIntrospector` are discarded: `JacksonAnnotationIntrospector.findEnumAliases()` overwrites every slot · Issue #6339 · FasterXML/jackson-databind · GitHub
Skip to content

Enum aliases from an appended AnnotationIntrospector are discarded: JacksonAnnotationIntrospector.findEnumAliases() overwrites every slot #6339

Closed

Description

@Marti2203

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

A module that adds an AnnotationIntrospector with appendAnnotationIntrospector() (so it becomes the secondary of an AnnotationIntrospectorPair) cannot contribute Enum aliases. Its aliases are ignored and the alias is rejected:

tools.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `...$Color` from String "rouge": not one of the values accepted for Enum class: [RED, GREEN]

The same introspector works when added with insertAnnotationIntrospector().

Cause: AnnotationIntrospectorPair.findEnumAliases() calls the secondary first and then the primary, "to give _primary higher precedence" (AnnotationIntrospectorPair.java:570-571 on 3.x, :599-600 on 2.x). That only works if the primary leaves slots without @JsonAlias unchanged. JacksonAnnotationIntrospector.findEnumAliases() instead assigns every slot:

aliasList[i] = enumToAliasMap.getOrDefault(enumValue.name(), new String[]{});

(JacksonAnnotationIntrospector.java:231 on 3.x, :289 on 2.x). This replaces whatever the secondary introspector set with an empty array. The older Class-based variant (2.x, JacksonAnnotationIntrospector.java:252-270) and findEnumValues() (:207-213) only assign when an annotation is present. The AnnotatedClass variant came in with #3832 (2.15), so this has probably been there since 2.15.

Version Information

3.x (3.3.0-SNAPSHOT, 4f153f0), 3.2.4, 2.x (2.23.0-SNAPSHOT, 425299b), 2.22.4.

Reproduction

enum Color { RED, GREEN }

static class AliasIntrospector extends NopAnnotationIntrospector {
    @Override
    public Version version() { return Version.unknownVersion(); }

    @Override
    public void findEnumAliases(MapperConfig<?> config, AnnotatedClass ac,
            Enum<?>[] enumValues, String[][] aliases) {
        aliases[0] = new String[] { "rouge" };
    }
}

static class AliasModule extends SimpleModule {
    @Override
    public void setupModule(SetupContext context) {
        super.setupModule(context);
        context.appendAnnotationIntrospector(new AliasIntrospector());
    }
}

JsonMapper mapper = JsonMapper.builder().addModule(new AliasModule()).build();
mapper.readValue("\"rouge\"", Color.class);
// InvalidFormatException; works with insertAnnotationIntrospector()

Expected behavior

Color.RED. The secondary introspector's aliases should be kept for values that have no @JsonAlias. A possible fix is to assign aliasList[i] in JacksonAnnotationIntrospector.findEnumAliases() only when the value has @JsonAlias, and otherwise fill in an empty array only if the slot is still null. With that change, the full 3.x test suite passes.

The open #6210 / #6211 (@JsonAlias with @JsonValue) change EnumResolver, not this method.

Additional context

This issue was found by an LLM-Enhanced Static Analysis Engine and verified manually.

Activity

  1. JooHyukKim commented on Oct 28, 2026

    @JooHyukKim
    Member

    Will take a look, tnx

  2. JooHyukKim commented on Oct 29, 2026

    @JooHyukKim
    Member

    @Marti2203 PR welcome!

    findEnumAliases() is meant to be in/out, but JacksonAnnotationIntrospector writes every slot, so when it's the primary in the pair it wipes whatever the secondary already put there.

    Agree with fixing it in JAI rather than in AnnotationIntrospectorPair. Once JAI has run, every slot is non-null, so the pair can't tell "no @JsonAlias here" apart from an explicit empty array.

    String[] aliases = enumToAliasMap.get(enumValues[i].name());
    if (aliases != null) {
        aliasList[i] = aliases;
    } else if (aliasList[i] == null) {
        aliasList[i] = new String[0];
    }

    Note : This change could probably go into 2.18.x version but not sure we can land this earlier

  3. added this to the 2.23.0 milestone on Oct 30, 2026
  4. added 3 commits that reference this issue on Oct 30, 2026
    50a52b6
    a9187b1
    d1e91cf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    2.23enumRelated to handling of Enum values

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions