Findbugs bugs me about a method which opens two Closeable instances, but I can’t understand why.
Source
public static void sourceXmlToBeautifiedXml(File input, File output)
throws TransformerException, IOException, JAXBException {
FileReader fileReader = new FileReader(input);
FileWriter fileWriter = new FileWriter(output);
try {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
} finally {
try {
fileReader.close();
} finally {
fileWriter.close();
}
}
}
Findbugs analysis
Findbugs tells me
Method [...] may fail to clean up java.io.Reader [...]
and points to the line with FileReader fileReader = ...
Question
Who is wrong: me or Findbugs?
FindBugs is correct: If the FileWriter’s constructor throws an exception, the file reader will not be closed. To verify this, try passing an invalid filename for
output.I’d do it as follows:
Note that the handling of exception thrown when closing could be improved, since leaving a finally-block by throwing an exception will cause the try-statement to terminate by throwing that exception, swallowing any exception thrown in the try-block, which generally would be more useful for debugging. See duffymo’s answer for a simple way on how to avoid this.
Edit: Since Java 7, we can use the try-with-resources statement, which permits correct and concicse handling of these corner cases: