Lib can not be used with Jackson 2.10.0 or later
Jackson 2.10 was released 2019-09-26. It contains a fix for https://github.com/FasterXML/jackson-core/issues/502, which makes snapshot building fail with the following exception:
io.github.jsonSnapshot.SnapshotMatchException: Failed `createInstance()`: io.github.jsonSnapshot.SnapshotMatcher$1 does not override method; it has to
at io.github.jsonSnapshot.SnapshotMatcher.lambda$defaultJsonFunction$0(SnapshotMatcher.java:116)
at io.github.jsonSnapshot.Snapshot.takeSnapshot(Snapshot.java:87)
at io.github.jsonSnapshot.Snapshot.toMatchSnapshot(Snapshot.java:43)
The cause of this is io.github.jsonSnapshot.SnapshotMatcher#buildDefaultPrettyPrinter where DefaultPrettyPrinter is extended, but now required createInstance method is not overridden.
This makes serializing JSON fail with the following stack trace:
java.lang.IllegalStateException: Failed `createInstance()`: io.github.jsonSnapshot.SnapshotMatcher$1 does not override method; it has to
at com.fasterxml.jackson.core.util.DefaultPrettyPrinter.createInstance(DefaultPrettyPrinter.java:256)
at com.fasterxml.jackson.core.util.DefaultPrettyPrinter.createInstance(DefaultPrettyPrinter.java:15)
at com.fasterxml.jackson.databind.ObjectWriter$GeneratorSettings.initialize(ObjectWriter.java:1299)
at com.fasterxml.jackson.databind.ObjectWriter._configureGenerator(ObjectWriter.java:1174)
at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1129)
at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1005)
at io.github.jsonSnapshot.SnapshotMatcher.lambda$defaultJsonFunction$0(SnapshotMatcher.java:114)
Any ideas when / if work can start on this? As Spring Boot 2.2.x uses Jackson 2.10.x this becomes a problem for everyone using Spring Boot 2.2.
Workaround
In all tests replace SnapshotMatcher.start() with SnapshotMatcher.start(Snapshot::asJsonString), where Snapshot#asJsonString is implemented like this:
public final class Snapshot {
private static final ObjectMapper objectMapper = buildObjectMapper();
private static final PrettyPrinter pp = buildDefaultPrettyPrinter();
/**
* Workaround for an incompatibility between latest Jackson and json-snapshot libs.
* <p>
* Intended to replace {@code io.github.jsonSnapshot.SnapshotMatcher#defaultJsonFunction}
*
* @see <a href="https://github.com/json-snapshot/json-snapshot.github.io/issues/27">Issue in json-snapshot project</a>
*/
public static String asJsonString(Object object) {
try {
return objectMapper.writer(pp).writeValueAsString(object);
} catch (JsonProcessingException e) {
throw new UncheckedIOException(e);
}
}
/**
* Unmodified copy of {@code io.github.jsonSnapshot.SnapshotMatcher#buildObjectMapper}
*/
private static ObjectMapper buildObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.setVisibility(
objectMapper
.getSerializationConfig()
.getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
return objectMapper;
}
/**
* Modified copy of {@code io.github.jsonSnapshot.SnapshotMatcher#buildDefaultPrettyPrinter}
*/
private static PrettyPrinter buildDefaultPrettyPrinter() {
DefaultPrettyPrinter pp =
new DefaultPrettyPrinter("") {
@Override
public DefaultPrettyPrinter createInstance() {
return this;
}
@Override
public DefaultPrettyPrinter withSeparators(Separators separators) {
this._separators = separators;
this._objectFieldValueSeparatorWithSpaces =
separators.getObjectFieldValueSeparator() + " ";
return this;
}
};
DefaultPrettyPrinter.Indenter lfOnlyIndenter = new DefaultIndenter(" ", "\n");
pp.indentArraysWith(lfOnlyIndenter);
pp.indentObjectsWith(lfOnlyIndenter);
return pp;
}
}
Hi @grimsa & @paul-pop! We're using the library to great success, thank you for that!
We recently updated our Jackson dependency and ran straight into this issue. The workaround works for us.
Is there a chance that there will be an update to json-snapshot in the future that fixes the issue?
Regarding a possible backwards-compatible fix: Shouldn't it be possible to also override createInstance() with Jackson <= 2.9? As far as I can tell, all DefaultPrettyPrinter versions already have it, so calling super.createInstance() should be enough…
But, of course, that's for you to decide :+1:
Thanks & have a good weekend!
Hi, @grimsa similar to the workaround you proposed, can we also introduce the workaround for having different modes of matching? i.e Introduce different matching modes