Java – Sonar is showing Bad Practice Method may fail to close stream on exception

java

Possible Duplicate:
Sonar violation: “Method may fail to close stream on exception”

I have a method that uses DataInputStream , code below :

DataInputStream in = null;
    ServletOutputStream outStream = null;
    FileInputStream fileIn = null;
    URL searchDirectory;
    try {
      searchDirectory = (java.net.URL) ctx.lookup("file/testHarnessDirectory");

      File file = new File(searchDirectory.getPath(), filename);
      int length = 0;
      outStream = response.getOutputStream();
      response.setContentType("application/octet-stream");
      response.setContentLength((int) file.length());

      response.setHeader("Content-Disposition", "attachement; filename=\"" + filename + "\"");
      byte[] byteBuffer = new byte[4096];
      fileIn = new FileInputStream(file);
      in = new DataInputStream(fileIn);

      while ((in != null) && ((length = in.read(byteBuffer)) != -1)) {
        outStream.write(byteBuffer, 0, length);
      }
      outStream.close();
      fileIn.close();
      in.close();
    }
    catch (NamingException e) {
      LOG.error("Exception", e);
      throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not download File", e);
    }
    catch (IOException e) {
      LOG.error("Exception", e);
      throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not submit File", e);
    }
    finally {
      try {
        if (fileIn != null) {
          fileIn.close();
        }
        if (in != null) {
          in.close();
        }
        if (outStream != null) {
          outStream.close();
        }
      }
      catch (IOException e) {
        LOG.error("Exception", e);
        throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not submit File", e);}}   

But Sonar is giving me : Bad practice – Method may fail to close stream on exception .
I have looked up this post:Sonar violation: "Method may fail to close stream on exception", but seemed incomplete to me. I could be wrong. Could anyone let me know, what is the simple way of closing the streams?

Best Answer

Check this section:

 try {
    if (fileIn != null) {
      fileIn.close();
    }
    if (in != null) {
      in.close();
    }
    if (outStream != null) {
      outStream.close();
    }
  }

and think, what will happen if fileIn.close() fails. Other two streams may remain open. Please put them in separate try-catch block. e.g.

 try {
    if (fileIn != null) {
      fileIn.close();
    }
  }catch (IOException e) {
    LOG.error("Exception: Could not close file stream", e);
    //throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not close file stream", e);
  }
 try {
    if (in != null) {
      in.close();
    }
  }catch (IOException e) {
    LOG.error("Exception: Could not close in stream"", e);
    //throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not close in stream", e);
  }
 try {
    if (outStream != null) {
      outStream.close();
    }
  }
  }catch (IOException e) {
    LOG.error("Exception: Could not close out stream", e);
    //throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not close out stream", e);
  }
Related Topic