Skip to content

ObjectMapper.valueToTree() Fails When DeserializationFeature.FAIL_ON_TRAILING_TOKENS Is Enabled #3308

@raphaelNguyen

Description

@raphaelNguyen

Describe the bug
ObjectMapper.valueToTree() throws the following error when being called on an ObjectMapper instance made with DeserializationFeature.FAIL_ON_TRAILING_TOKENS feature enabled.

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Trailing token (of type START_OBJECT) found after value (bound as com.fasterxml.jackson.databind.JsonNode): not allowed as per DeserializationFeature.FAIL_ON_TRAILING_TOKENS
at [Source: UNKNOWN; byte offset: #UNKNOWN]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportTrailingTokens(DeserializationContext.java:1814)
at com.fasterxml.jackson.databind.ObjectMapper._verifyNoTrailingTokens(ObjectMapper.java:4783)
at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4656)
at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:2941)
at com.fasterxml.jackson.databind.ObjectMapper.valueToTree(ObjectMapper.java:3392)

Version information
2.13.0

To Reproduce
Create an ObjectMapper with the fail on trailing tokens option enabled and call valueToTree() using that mapper.
ObjectMapper mapper = JsonMapper.builder().enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS).build;

Expected behavior
ObjectMapper should return a JsonNode representation of the object without any error.

Additional context
From what I can see debugging the method valueToTree(). It seems that the method works by serializing the java Object into a TokenBuffer before deserializing that buffer back into JsonNode.

However, as can be seen in the snippet referenced below, a recent change (2e986df) has added a line to serialize the java Object into the buffer (context.serializeValue(buf, fromValue)) without deleting the old code that does the same thing (writeValue(buf, fromValue)). This cause the buffer to contain 2 copies of the deserialized object instead of one.

The subsequent readTree() will serialize the 1st copy of the object out and judge the remaining 2nd copy of the serialized object to be trailing garbage token and failed according to the DeserializationFeature.FAIL_ON_TRAILING_TOKENS feature.

It seems to me that the fix is to simply remove the redundant call to writeValue in this method. Please advise if this is indeed a problem or I've made a mistake somewhere.

try {
context.serializeValue(buf, fromValue);
writeValue(buf, fromValue);
try (JsonParser p = buf.asParser()) {
return readTree(p);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions