The reader that stays open on error
A easy Java puzzle in the resource leaks family. One line below contains a real bug. Try to spot it first, then read why it fails and how to fix it.
Highlighted: line 8. Play this one as a puzzle without the answer.
What is wrong
If readLine returns null, line.length() throws before close runs, and any IOException also skips it. Each failure leaks a file handle, and after enough of them the process fails with Too many open files.
The fix
How to avoid it next time
Open every closeable resource in a try-with-resources header so it is closed on every path.
Want the background? Read try-with-resources in the Java concepts library.
About resource leaks
Files, streams, sockets, connections and statements hold operating system handles that the garbage collector will not release promptly. A leak often shows up only in production after hours of load as too many open files or an exhausted connection pool.
In code review: Every constructor of a closeable type should sit in a try-with-resources header. Check the exceptional path as well as the normal one.
More puzzles in this family
Frequently asked questions
What is the bug in "The reader that stays open on error"?
If readLine returns null, line.length() throws before close runs, and any IOException also skips it. Each failure leaks a file handle, and after enough of them the process fails with Too many open files. The faulty line is line 8: br.close();
How do I fix it?
Replace it with: try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); }. Open every closeable resource in a try-with-resources header so it is closed on every path.
How do I catch resource leaks in code review?
Every constructor of a closeable type should sit in a try-with-resources header. Check the exceptional path as well as the normal one.
Is there a new puzzle every day?
Yes. The daily Spot the Bug puzzle picks one of these snippets for each UTC day, with the difficulty set by the weekday. Your streak is stored only in your browser.