Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialising Either: IncompatibleClassChangeError #174

Open
mcac0006 opened this issue Nov 28, 2020 · 1 comment
Open

Serialising Either: IncompatibleClassChangeError #174

mcac0006 opened this issue Nov 28, 2020 · 1 comment

Comments

@mcac0006
Copy link

final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new VavrModule());

// yields [1]
System.out.println(objectMapper.writeValueAsString(List.of(1)));

final Cat cat = new Cat();
cat.name = "Bianca";
final Either<Cat, Dog> either = Either.left(cat);

// yields java.lang.IncompatibleClassChangeError: Found class io.vavr.control.Either, but interface was expected
System.out.println(objectMapper.writeValueAsString(either));

Some observations:

  • evaluating io.vavr.jackson.datatype.serialize.EitherSerializer#serialize's own value parameter is just fine through debug watch.
    Unless I am missing something, I think it may be a generics issue/type erasure in EitherSerializer (Either.One<Cat> is technically not a direct subtype of Either<?, ?>).
@mincong-h
Copy link
Member

Hi @mcac0006 , thanks for reporting this. It sounds like a bug. On my side, I tried to reproduce it but without success. Could you provide more detail, such as the version of Vavr-Jackson, the version of Jackson, the source code of Cat and Dog?

Here is the my attempt but both tests passed, using the last commit 0538bdb on master branch:

package io.vavr.jackson.issues;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.vavr.control.Either;
import io.vavr.jackson.datatype.VavrModule;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class Issue174Test {
    @Test
    void eitherLeft() throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new VavrModule());
        Cat cat = new Cat();
        cat.name = "Bianca";
        Either<Cat, Dog> either = Either.left(cat);

        String json = objectMapper.writeValueAsString(either);
        assertEquals("[\"left\",{\"name\":\"Bianca\"}]", json);

        Either<Cat, Dog> restored = objectMapper.readValue(json, new TypeReference<Either<Cat, Dog>>() {});
        assertEquals("Bianca", restored.getLeft().name);
    }

    @Test
    void eitherRight() throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new VavrModule());

        Dog dog = new Dog();
        dog.name = "Labrador";
        Either<Cat, Dog> either = Either.right(dog);

        String json = objectMapper.writeValueAsString(either);
        assertEquals("[\"right\",{\"name\":\"Labrador\"}]", json);

        Either<Cat, Dog> restored = objectMapper.readValue(json, new TypeReference<Either<Cat, Dog>>() {});
        assertEquals("Labrador", restored.get().name);
    }

    static class Cat {
        @JsonProperty("name")
        String name;
    }

    static class Dog {
        @JsonProperty("name")
        String name;
    }
}

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

No branches or pull requests

2 participants