I am trying to get the following example working:
@Value
@JsonDeserialize(builder = SomeClass.Builder.class)
@Builder(builderClassName = "Builder")
public static class SomeClass {
@Wither
ImmutableList<String> words;
@JsonPOJOBuilder(withPrefix = "")
public static class Builder {
}
}
@Test
@SneakyThrows
public void serializeTest() {
ObjectMapper objectMapper = new ObjectMapper();
SomeClass someClass = SomeClass.builder()
.words(ImmutableList.of("word1", "word2", "word3"))
.build();
String jsonString = objectMapper.writeValueAsString(someClass);
log.info("serialized: {}", jsonString);
SomeClass newSomeClass = objectMapper.readValue(jsonString, SomeClass.class);
log.info("done");
newSomeClass.words.forEach(w -> log.info("word {}", w));
}
however it fails with
Caused by: java.lang.IllegalArgumentException: Cannot find a deserializer for non-concrete Collection type [collection type; class com.google.common.collect.ImmutableList, contains [simple type, class java.lang.String]]
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.createCollectionDeserializer(BasicDeserializerFactory.java:1205)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:399)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
From this answer, I attempted something like:
@Value
@JsonDeserialize(builder = SomeClass.Builder.class)
@Builder(builderClassName = "Builder")
public static class SomeClass {
@Wither
@JsonDeserialize(using = ImmutableListDeserializer.class)
ImmutableList<String> words;
@JsonPOJOBuilder(withPrefix = "")
public static class Builder {
}
}
@Test
@SneakyThrows
public void serializeTest() {
ObjectMapper objectMapper = new ObjectMapper();
SomeClass someClass = SomeClass.builder()
.words(ImmutableList.of("word1", "word2", "word3"))
.build();
String jsonString = objectMapper.writeValueAsString(someClass);
log.info("serialized: {}", jsonString);
SomeClass newSomeClass = objectMapper.readValue(jsonString, SomeClass.class);
log.info("done");
newSomeClass.words.forEach(w -> log.info("word {}", w));
}
but that fails with:
Caused by: java.lang.IllegalArgumentException: Cannot find a deserializer for non-concrete Collection type [collection type; class com.google.common.collect.ImmutableList, contains [simple type, class java.lang.String]]
Due to the constraints of the project I'm working on, I cannot modify the object mapper. So I cannot simply do:
objectMapper.registerModule(new GuavaModule());
which would have worked.
Is there any other straightforward way to get a simple ImmutableList deserialization working?
Edit: I managed to get a different error with below:
@Value
@JsonDeserialize(builder = SomeClass.Builder.class)
@Builder(builderClassName = "Builder")
public static class SomeClass {
@Wither
ImmutableList<String> strings;
@JsonPOJOBuilder(withPrefix = "")
public static class Builder {
@JsonDeserialize(using = ImmutableListDeserializer.class)
public Builder strings(ImmutableList<String> strings) {
this.strings = strings;
return this;
}
}
}
@Test
@SneakyThrows
public void serializeTest() {
ObjectMapper objectMapper = new ObjectMapper();
SomeClass someClass = SomeClass.builder()
.strings(ImmutableList.of("word1", "word2", "word3"))
.build();
String jsonString = objectMapper.writeValueAsString(someClass);
log.info("serialized: {}", jsonString);
SomeClass newSomeClass = objectMapper.readValue(jsonString, SomeClass.class);
log.info("done");
newSomeClass.strings.forEach(w -> log.info("word {}", w));
}
which throws:
Caused by: java.lang.IllegalArgumentException: Class com.fasterxml.jackson.datatype.guava.deser.ImmutableListDeserializer has no default (no arg) constructor
maybe that is easier to solve if I could build a no arg constructor for ImmutableListDeserializer, or something like that