-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
ObjectMapper.readTree()
methods do not return null
on end-of-input
#1406
Comments
@fabriziocucci Thank you for reporting this. My first thought here was that the documentation is wrong, since all similar read methods do this. But I also know that there is a difference in that whereas regular data-binding is limited to just I will have to think about this bit more. In the meantime, if you do need to allow for optional content, you may choose to use |
@cowtowncoder thanks for your prompt reply. I see your point but, probably, using If I'm not wrong, based on your suggestion, I would need to do something like this: public static JsonNode fromInputStream(InputStream inputStream) {
try {
MappingIterator<JsonNode> configurations = YAML_OBJECT_MAPPER.reader(JsonNode.class).readValues(inputStream);
if (configurations.hasNext()) {
JsonNode configuration = configurations.next();
if (configurations.hasNext()) {
throw new IllegalStateException("Found multiple configurations!");
} else {
return configuration;
}
} else {
return emptyConfiguration();
}
} catch (Exception exception) {
throw new IllegalStateException(exception);
}
} which probably does the trick but...it looks a bit messy, doesn't it? I was currently doing something like this: public static JsonNode fromInputStream(InputStream inputStream) {
try {
return (inputStream.available() > 0) ?
YAML_OBJECT_MAPPER.readTree(inputStream) :
emptyConfiguration();
} catch (Exception exception) {
throw new IllegalStateException(exception);
}
} which is not good either because highly relies on how the By the way, I'm asking because I'm kind of having fun with this library and I'm sure your insights will be more than helpful! |
I don't see why use of However: if you prefer alternate method, you could also create a |
Exactly, that was my point and yes, I prefer the second solution for now, thanks a lot for the suggestion! 😉 But while I was playing with the JsonParser API, I noticed something else (sorry, bear with me). We said that the following line:
correctly throws in case of empty streams and its Javadoc will be aligned to reflect this. But the following line:
actually returns Now my question is: shouldn't the two API be aligned? |
I was curious to see why that happens and I ended up swimming in debug mode! 😅 While the second option (i.e. public <T extends TreeNode> T readTree(JsonParser p)
throws IOException, JsonProcessingException
{
/* 02-Mar-2009, tatu: One twist; deserialization provider
* will map JSON null straight into Java null. But what
* we want to return is the "null node" instead.
*/
/* 05-Aug-2011, tatu: Also, must check for EOF here before
* calling readValue(), since that'll choke on it otherwise
*/
DeserializationConfig cfg = getDeserializationConfig();
JsonToken t = p.getCurrentToken();
if (t == null) {
t = p.nextToken();
if (t == null) {
return null;
}
}
JsonNode n = (JsonNode) _readValue(cfg, p, JSON_NODE_TYPE);
if (n == null) {
n = getNodeFactory().nullNode();
}
@SuppressWarnings("unchecked")
T result = (T) n;
return result;
} the first one (i.e. protected JsonToken _initForReading(JsonParser p) throws IOException
{
_deserializationConfig.initialize(p); // since 2.5
/* First: must point to a token; if not pointing to one, advance.
* This occurs before first read from JsonParser, as well as
* after clearing of current token.
*/
JsonToken t = p.getCurrentToken();
if (t == null) {
// and then we must get something...
t = p.nextToken();
if (t == null) {
// Throw mapping exception, since it's failure to map,
// not an actual parsing problem
throw JsonMappingException.from(p, "No content to map due to end-of-input");
}
}
return t;
} Now, it may be perfectly OK to have different behaviors but, as a user, I'm a bit surprised to discover this difference. |
@fabriziocucci at this point, I am sorry I ever added various Now. I am beginning to think that perhaps documentation-indicated behavior does make sense to support. Returning |
@cowtowncoder I'm sorry if my obsession for consistency gave you some headache 😅 but I understand how hard it is changing at this stage! Although my preference is always for returning an empty |
ObjectMapper.readTree()
methods do not return null
on end-of-input
Note to curious readers: there was yet more wailing and gnashing of teeth, for... #2211 was found. |
Hi,
the Javadoc for the
readTree(InputStream)
method goes like this:But if I try to use it with an empty file (through the
FileInputStream
) I get the following exception:I was wondering whether it is the code not to be aligned with the expected behavior or it is just the Javadoc.
Ideally, from a consumer prospective, it would have been nice to return a sort of "identity"
JsonNode
(e.g. an emptyJsonNodeType.OBJECT
or aJsonNodeType.MISSING
) in case of empty file, stream, etc. But I can imagine that such a change (if it even makes sense) could cause some backward compatibility issue.The text was updated successfully, but these errors were encountered: