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

(2.8) ObjectMapper._readMapAndClose() swallows IOException on close() #629

Closed
cowwoc opened this issue Nov 24, 2014 · 7 comments
Closed
Assignees
Milestone

Comments

@cowwoc
Copy link

cowwoc commented Nov 24, 2014

ObjectMapper._readMapAndClose() contains this code:

            try {
                jp.close();
            } catch (IOException ioe) { }

Does it really make sense to do this? I know that exceptions are unlikely to be thrown when closing a file that was only read file (there is no data to flush on close()) but the method already declares it throws IOException so what's the harm of letting the exception bubble up?

@cowtowncoder
Copy link
Member

The problem here is that in many cases this would end up hiding the real exception. That is, when closing parser as a result of an exception, not catching one from close would basically hide the real root cause, and lead to (more) difficult to debug failures.
In fact, this has been a problem with Avro codec as it tends to fail with nasty RuntimeExceptions like NPEs (I really dislike that implementation; failures are arbitrary).

If this can be avoided this exception can (and should) pass through; but I think I wasn't able to find a clean to achieve this. If you can figure out a better way to do this, I am definitely open to improvements.

@cowwoc
Copy link
Author

cowwoc commented Nov 25, 2014

@cowtowncoder This is handled automatically by https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#addSuppressed-java.lang.Throwable-

I hope you require at least Java7 for Jackson (since Java6 is EOLed).

@cowtowncoder
Copy link
Member

No. Jackson is at low enough level that 2.4 was the first version to have baseline of Java6 (earlier Java5 was the baseline), and for core components that won't change for 2.5. Just because Oracle has EOL'd support does not mean that there weren't many installations that still run on Java6.
We can start discussions wrt 2.6, however, and it may be possible to increase baseline for that verion.

So this is good to know for Java7; I wasn't aware of this facility. Thank you for the link.

I will leave this issue open, then.

Also... while I am not big fan of using Reflection for regular code, this is one place where could consider dynamically discovering addSuppressed(), and using it if available.
That would allow use even before upgrading baseline.

@cowwoc
Copy link
Author

cowwoc commented Nov 25, 2014

@cowtowncoder QueryDSL implemented this very nicely on a bug I recently reported. Check out the bug description here: querydsl/querydsl#1007 (comment) and their implementation here: querydsl/querydsl#1008

Because they use a static block, selection happens once. There is no performance overhead for subsequent calls.

@cowwoc
Copy link
Author

cowwoc commented Nov 25, 2014

Oh, by the way... you don't need to invoke addSuppressed() manually. If you use try-with-resources this gets invoked on your behalf automatically.

@cowtowncoder
Copy link
Member

Since Jackson 2.7 allows use of Java 7 types (although has to be dynamic wrt runtime), and 2.8 will allow regular use of language features, I think this can finally be done in 2.8. Will edit title to reflect that.

@cowtowncoder cowtowncoder added this to the 2.8 milestone Dec 11, 2015
@cowtowncoder cowtowncoder self-assigned this Dec 11, 2015
@cowtowncoder cowtowncoder changed the title ObjectMapper._readMapAndClose() swallows IOException on close() (2.8) ObjectMapper._readMapAndClose() swallows IOException on close() Dec 11, 2015
@cowtowncoder
Copy link
Member

Fixed via #1221, for 2.8.0. IOException from close is not swallowed if it's the primary problem; if it's secondary, it will be linked as suppressed for primary exception so it is still retained.

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