Home > Software engineering >  Sonar Error: Use try-with-resources or close this "ZipOutputStream" in a "finally&quo
Sonar Error: Use try-with-resources or close this "ZipOutputStream" in a "finally&quo

Time:10-30

I implemented a zip download method in a Spring Boot application with Java. I tried several different solutions but I am still receiving: Use try-with-resources or close this "ZipOutputStream" in a "finally" clause error from Sonar.

Here you can find my implementation in the service. I would be so happy if you can direct me to solve this issue!

@Override
public void downloadZipBySeasonId(int seasonId, HttpServletResponse response) throws IOException {
.
.
.
    if(!items.isEmpty()) {
        ZipOutputStream zipOut = null;
        try {
            zipOut = new ZipOutputStream(response.getOutputStream());  // Sonar points this line!
            for (int i = 1; i <= items.size(); i  ) {
                LetterEntity letter = items.get(i - 1);
                ZipEntry zipEntry = new ZipEntry(letter.getLetterName());
                zipOut.putNextEntry(zipEntry);
                StreamUtils.copy(letter.getLetterContent(), zipOut);
                zipOut.closeEntry();
            }
        }
        catch (IOException e) {
            e.printStackTrace();
            throw new IllegalArgumentException("Could not zip succesfully!");
        }
        finally {
            if(zipOut != null) {
                zipOut.finish();
                zipOut.close();
            }
        }
        response.setStatus(HttpServletResponse.SC_OK);
        response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""   zipFileName   "\"");
    } else {
        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
    }
}

CodePudding user response:

Try with ressources close the ressources automatically (ressources like Streams , Buffereds..) you dont need to close the readers or writers in the finally block , you dont need to write the finally block , also you can avoid writing the catch block..

example

 try (BufferedReader r = Files.newBufferedReader(path1);
  BufferedWriter w = Files.newBufferedWriter(path2))
 {
  //protected code
 }
 catch (Exception e) {
  // exeption handler
 } 

documentation : https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

CodePudding user response:

Applying try with resources to initial code would be as below. Here you dont have to close the stream in a finally block. Its closed when try catch block is exited. Sonar issue was there because of the null check. if(!items.isEmpty()) {

        try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());){
            for (int i = 1; i <= items.size(); i  ) {
                LetterEntity letter = items.get(i - 1);
                ZipEntry zipEntry = new ZipEntry(letter.getLetterName());
                zipOut.putNextEntry(zipEntry);
                StreamUtils.copy(letter.getLetterContent(), zipOut);
                zipOut.closeEntry();
            }
        }
        catch (IOException e) {
            e.printStackTrace();
            throw new IllegalArgumentException("Could not zip succesfully!");
        }

        response.setStatus(HttpServletResponse.SC_OK);
        response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""   zipFileName   "\"");
    } else {
        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
    }
  • Related