Проблема с Sonarqube — измените эту «попытку» на попытку с ресурсами. Как обрабатывать условные ресурсы?

#java #sonarqube #try-with-resources

#java #sonarqube #попытка с ресурсами

Вопрос:

Проверил похожие вопросы по этой теме, но я не нашел решения для своего варианта использования.
Следующий метод показывает проблему сонара с Major code smell as — Change this "try" to a try-with-resources.

 private void readExcel() {
        Workbook workbook = null;
        BufferedReader br = null;
        
        try {
            File file = path.toFile();
            if (file.getName().endsWith(FILE_TYPES.XLS.value) amp;amp; (file.length() / (1024 * 1024)) < 25) {
                workbook = new HSSFWorkbook(new POIFSFileSystem(file));
                Sheet sheet = workbook.getSheetAt(0);
                readExcel(sheet);
            } else if ((file.getName().endsWith(FILE_TYPES.XLSX.value)) amp;amp; (file.length() / (1024 * 1024)) < 25) {
                workbook = new XSSFWorkbook(file);
                Sheet sheet = workbook.getSheetAt(0);
                readExcel(sheet);
            } else if (file.getName().endsWith(FILE_TYPES.CSV.value)) {
                // Apache POI cant read/write CSV. Hence using Java IO.
                br = new BufferedReader(new FileReader(file));
                readExcel(br);
            }
        } catch (IOException | InvalidFormatException ex) {
                // set invalid flags and call clean-up
        } finally {
            try {
                if (workbook != null) {
                    workbook.close();
                }
                if (br != null) {
                    br.close();
                }
            } catch (IOException ex) {
                // set invalid flags and call clean-up
            }
        } // try-catch-finally closed
    }
  

Это ложноположительная проблема сонара?

Комментарии:

1. По крайней мере, BufferedReader может быть блоком try-with-resources, так что сделайте это.

Ответ №1:

HSSFWorkbook является AutoCloseable .
XSSFWorkbook является AutoCloseable .
BufferedReader является AutoCloseable .

Всем им нужны свои собственные попытки с ресурсами.

Избавьтесь от Workbook workbook = null; и BufferedReader br = null; , и кода в finally блоке, потому что это все в старом стиле, предварительно попробовав с ресурсами.

 private void readExcel() {
    try {
        File file = path.toFile();
        if (file.getName().endsWith(FILE_TYPES.XLS.value) amp;amp; (file.length() / (1024 * 1024)) < 25) {
            try (Workbook workbook = new HSSFWorkbook(new POIFSFileSystem(file))) {
                Sheet sheet = workbook.getSheetAt(0);
                readExcel(sheet);
            }
        } else if ((file.getName().endsWith(FILE_TYPES.XLSX.value)) amp;amp; (file.length() / (1024 * 1024)) < 25) {
            try (Workbook workbook = new XSSFWorkbook(file)) {
                Sheet sheet = workbook.getSheetAt(0);
                readExcel(sheet);
            }
        } else if (file.getName().endsWith(FILE_TYPES.CSV.value)) {
            // Apache POI cant read/write CSV. Hence using Java IO.
            try (BufferedReader br = new BufferedReader(new FileReader(file))) {
                readExcel(br);
            }
        }
    } catch (IOException | InvalidFormatException ex) {
        // set invalid flags and call clean-up
    }
}
  

Комментарии:

1. Учитывая, что первые две операции используют общий базовый тип Workbook и в остальном тоже идентичны, я бы не сказал, что им нужна собственная попытка с ресурсами.

2. @Holger Ну, им нужны свои собственные вызовы конструктора, и поскольку вызов конструктора обычно находится в try скобках, они получают свои собственные блоки. Но вы правы, их можно объединить, но это вряд ли необходимо для этого простого кода.

3. Конечно, у людей разные мнения о том, какой объем дублирования кода допустим. Поскольку совместное использование кода немного повысит сложность, пять строк кода являются пограничным случаем. Для меня, даже file.getName() повторив три раза, кажется неправильным…