Dumping Enum breaks in 1.19 - 1.21

Issue #409 resolved
Evan Ward
created an issue

First, thanks for a great product with snakeyaml.

While upgrading snakeyaml 1.10 to 1.21 I noticed an backward incompatibility with how snakeyaml dumps Java enums starting in 1.19. I've included a test case below that shows what I expect to happen. Essentially I would expect the enum to be dumped as just the name of the enum, just as it is in 1.10 through 1.18. Instead the enum is dumped as !!YamlTest$MyEnum$2 'B', which causes a YAMLException when trying to load it.

I am using Java 8.

public class YamlTest {

    public static class Bean {

        public MyEnum myEnum = MyEnum.B;

    }

    public enum MyEnum {
        A {}, B {};
    }

    /**
     * Test dumping enums. Works on Yaml 1.10 through 1.18. Fails on Yaml 1.19 through
     * 1.21.
     */
    @Test
    public void testYaml() {
        Yaml yaml = new Yaml();
        String text = yaml.dumpAs(new Bean(), Tag.MAP, FlowStyle.AUTO);
        Bean actual = yaml.loadAs(text, Bean.class);
        assertThat(actual.myEnum, is(MyEnum.B));
        assertThat(text, is("{myEnum: B}\n"));
    }

}

Comments (13)

  1. Evan Ward reporter

    Hi Andrey, thanks for the response. I reduced the code to the minimum amount needed to reproduce the bug. In Java each enum value can be it its own class which makes them much more powerful than in other languages. The practice is recommended by Joshua Bloch in "Effective Java" when all the instances of a certain type can be enumerated at compile time.

    To give a real world example, I noticed the issue when I was working with https://www.orekit.org/static/xref/org/orekit/frames/LOFType.html

  2. Andrey Somov repo owner

    I see the point now. The next 2 weeks we will not be able to work on this issue. Hopefully, we can fix it and release with the next version at the end of August.

  3. Andrey Somov repo owner

    Fix issue 409: check only property.getType()

    Refactor the way to detect if the full tag can be omitted (and !!str is used instead). Instead of checking whether the class for property and the class for the actual value is the same we can just check that the property class is not java.lang.Enum

    → <<cset 93a3f65e578b>>

  4. Evan Ward reporter

    I'll continue using 1.18 until the fix is released since I don't need any features from 1.19+. I'll update when 1.22 is released. Thanks for implementing the fix quickly.

  5. Log in to comment