Форум программистов, компьютерный форум, киберфорум
Java EE (J2EE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789

Как быть, когда блок finally нужен и как применить com.google.common.io.Closer

22.09.2018, 13:58. Показов 1428. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
вот например в таком случае.


Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
 
import static com.training.carshop.validate.object.ValidateObjectNotNull.isNullObjects;
import static com.training.carshop.validate.string.ValidateArgumentString.isBlank;
 
 
/**
 * Создан разработчиком IT
 * Дата 26.08.2018
 */
public class ConnectionPool extends Constants {
 
    private static final ConnectionPool pool = new ConnectionPool();
 
    public static ConnectionPool getPool() {
        return pool;
    }
 
 
    private DataSource dataSource;
 
    private ConnectionPool() {
        Properties properties;
        String nameJndiResource;
        try {
            if (isBlank(PATH_TO_PROPERTIES_JNDI)) {
                throw new ValidateException(MESSAGE_NOT_EMPTY_STR);
            }
 
            properties = new ClassPathPropertiesReader().getProperties(PATH_TO_PROPERTIES_JNDI);
 
        } catch (IOException e) {
            throw new ConnectionException(MESSAGE_EXCEPTION_FILE_JNDI, e);
        }
 
        isNullObjects(properties);
 
        try {
            nameJndiResource = properties.getProperty(JNDI_LINK);
            Context initContext = new InitialContext();
            Context rootContext = (Context) initContext.lookup("java:comp/env");
            dataSource = (DataSource) rootContext.lookup(nameJndiResource);
        } catch (NamingException e) {
            throw new ConnectionException(MESSAGE_LOOKUP_JNDI, e);
            /* Надо подумать, как сделать не проброс исключения и остановку программы, а
            в случае отлова ошибки подключения, выполнить переход на страницу, в которой
            будет сообщено пользователю, что база данных не работатет и нужно попробовать
            подключится позже.
             А адиминстратору выдать на косноль предупреждение, а также сформировать отправку
             сообщения на почту
             */
        }
    }
 
    public Connection getConnection() {
        try {
            dataSource.getConnection().setAutoCommit(false);
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new ConnectionException(MESSAGE_CONNECTION, e);
        }
    }
 
    /**
     * Методы для закрытия поптоков
     * Применяется принцип делегирования
     */
    public void closeDbResources(Connection connection) {
        closeDbResources(connection, null, null);
    }
 
    public void closeDbResources(ResultSet resultSet) {
        closeDbResources(null, null, resultSet);
    }
 
    public void closeDbResources(Connection connection, Statement statement) {
        closeDbResources(connection, statement, null);
    }
 
 
    private void closeDbResources(Connection connection, Statement statement, ResultSet resultSet) {
        closeResultSet(resultSet);
        closeStatement(statement);
        closeConnection(connection);
    }
 
 
    private void closeConnection(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                System.out.println("Error: Connection has not been closed!");
            }
        }
    }
 
    private void closeStatement(Statement statement) {
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                System.out.println("Error: Statement has not been closed!");
            }
        }
    }
 
    private void closeResultSet(ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                System.out.println("Error: ResultSet has not been closed!");
            }
        }
    }
 
    /*  отменить действия с базой данных, в  текущем запросe (отменить транзакцию)
       Отмена всех изменений, внесенных в текущую транзакцию
       и освобождение всех блокировок базы данных, удерживаемые в данный момент
       текущим объектoм Connection. Этот метод должен быть
       использован только при отключенном режиме автоматической фиксации транзакций
      (auto-commit mode = disable).
     @exception SQLException - при возникновении ошибки доступа к базе данных,
     rollback() метод вызывается при участии в распределенной транзакции,
     этот метод вызывают на закрытом соединении, или когда объект connection
     находится в auto-commit mode  */
    public static void rollback(Connection conn) {
        try {
            conn.rollback();
        } catch (Exception e) {
            System.out.println("Rollback changes as a result of a transaction that failed to undo.");
        }
    }
 
 
}



Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
     * @see CarDao
     * @param carEntity - объект для хранения одной записи обрабатываемого бизнес-объекта
     */
    @Override
    public CarEntity storeCar(CarEntity carEntity) throws DaoException {
 
        isNullObjects(carEntity);
 
        Connection connection;
        PreparedStatement statement = null;
        String sql;
 
        sql = "INSERT INTO `cars` (`model`, `color`, `speed`, `fuel_consumption`, " +
                "`quantity`, `cost`, `date_delivery`,`uuid`) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
 
        connection = ConnectionPool.getPool().getConnection();
 
        try {
            statement = connection.prepareStatement(sql);
            statement.setString(ONE, carEntity.getModel());
            statement.setString(TWO, carEntity.getColor());
            statement.setInt(THREE, carEntity.getSpeed());
            statement.setInt(FOUR, carEntity.getFuelConsumption());
            statement.setInt(FIVE, carEntity.getQuantity());
            statement.setInt(SIX, carEntity.getCost());
            setDateToStatement(statement, SEVEN, carEntity.getDateDelivery());
            statement.setString(EIGHT, carEntity.getUuid());
 
            statement.executeUpdate();
            connection.commit();
 
            Integer storeId = loadStoreId(statement);
            CarEntity storeCar;
 
            if(isNotValidateArgument(storeId)){
 
                return new CarEntity();
            }
 
 
            storeCar = loadCarById(storeId);
            return storeCar;
 
        } catch (SQLException e) {
            rollback(connection);
            throw new DaoException(MESSAGE_STATEMENT,e);
        } finally {
            ConnectionPool.getPool().closeDbResources(connection, statement);
        }
    }



как избавиться от таких блоков finally ?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.09.2018, 13:58
Ответы с готовыми решениями:

Когда выполнятся .then/catch/finally после того как Promise завершится?
В учебнике написано А что здесь является текущим кодом? Когда витруальная машина начнет выполнять микрозадачи из очереди? Когда...

Как применить свойство hover к элементу списка, когда элемент - ссылка
Добрый день, подскажите пожалуйста, как применить свойство hover к элементу списка, чтобы поменять стиль при наведении на весь элемент? ...

Как можно в textarea применить ::first-line, или как к первой строки применить стиль, внутри данного элемента
Да и вообще, для этого можно ли еще что-либо вложить в данный элемент, кроме как текста? Добавлено через 2 часа 3 минуты вопрос...

12
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
22.09.2018, 16:19
Цитата Сообщение от masli Посмотреть сообщение
как избавиться от таких блоков finally?
Тебе же уже писали воспользоваться try-with-resources
0
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789
22.09.2018, 19:13  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
Тебе же уже писали воспользоваться try-with-resources
Конструкцию try-with-resources ввели в Java 7. Она дает возможность объявлять один или несколько ресурсов в блоке try, которые будут закрыты автоматически без использования finally блока.

В качестве ресурса можно использовать любой объект, класс которого реализует интерфейс java.lang.AutoCloseable или java.io.Closable.

Так как мне поможет здесь конструкция try-with-resources?

DataSource не наследует данных классов.
Там где можно было я реализовал...

А как с этим быть.

Java
1
  ConnectionPool.getPool().closeDbResources(connection, statement);
Если знаете скажите, не знаете как, так и скажите...
0
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
22.09.2018, 19:31
Цитата Сообщение от masli Посмотреть сообщение
А как с этим быть.
прочитать как работает try-with-resources и написать соответствующий код?
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
22.09.2018, 21:10
Цитата Сообщение от masli Посмотреть сообщение
Так как мне поможет здесь конструкция try-with-resources?
Прямо.

Цитата Сообщение от masli Посмотреть сообщение
DataSource не наследует данных классов.
Каких данных классов? И при чём тут вообще DataSource?

Цитата Сообщение от masli Посмотреть сообщение
А как с этим быть.
Это удалить.

Цитата Сообщение от masli Посмотреть сообщение
Если знаете, скажите
Знаю. Тебе уже говорили, и не раз. Даже ссылку на статью с примером дали.
0
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789
27.09.2018, 11:58  [ТС]
Как я и говорил, в данном случае, оператор try-with-resources - не возможно применить.
Для того, чтобы не было подавления исключения, все равно нужно использовать блок try-catch-fynally

Например, вот так:

Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    private static OutputStream openOutputStream() throws IOException {
 
        return null;
    }
 
    private static void excCheck(){
 
        OutputStream stream = null;
        Throwable mainException = null;
        try {
            // что-то делаем со stream
            stream = openOutputStream();
        } catch (Throwable t) {
            mainException = t;
            // обрабатываем исключение
        } finally {
 
            try {
                stream.close();
            } catch (Throwable unused) {
                /* игнорируем, так как есть основное исключение
                 можно добавить лог исключения (по желанию)
                Лог создается, если ресурс не закрылся (например, stream = null). 
                Так как закрытие потока невозможно обработать, поэтому нет смысла что-либо
                ловить в данном случае
 
                Throwable unused - подавит вывод исключения (java.lang.NullPointerException) в StackTrace,
                если объект закрываемого
                ресурса равен null*/
            }
        }
    }


Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 public static void resourcesProcess() {
        OutputStream stream = null;
        Throwable mainException = null;
 
        try {
            /*
            что-то делаем со stream
             */
            String pathToFile = "c:\\driver";
            FileInputStream fileInputStream = new FileInputStream(pathToFile);
            stream = openOutputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
 
            System.out.println("Блок try");
 
        } catch (Throwable t) {
            mainException = t;
            /*
             обрабатываем исключение
              */
            System.out.println("Исключение в блоке catch");
            System.out.println("t = " + mainException);
        } finally {
 
            try {
                stream.close();
            } catch (Throwable unused) {
                System.out.println("++++++++++++++++++++++++++");
                System.out.println("Исключение в блоке finally");
            }
        }
    }
 
 
    private static OutputStream openOutputStream() throws IOException {
 
        return null;
    }


решено
1
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
27.09.2018, 12:43
Почитайте почему не стоит ловить Throwable. И я бы задумался почему объект закрываем ого ресурса null и надо ли null закрывать.
0
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789
27.09.2018, 13:53  [ТС]
Цитата Сообщение от JIeIIIa Посмотреть сообщение
И я бы задумался почему объект закрываем ого ресурса null и надо ли null закрывать.
Не понял что означает это предложение.

Добавлено через 2 минуты
Если вы имеете ввиду пример выше, то stream = null, это всего лишь имитация того, что возможно в момент попытки закрытия в блоке finally ресурса, он уже к этому моменту будет равен null, либо само закрытие не удастся по каким-то иным причинам.
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
27.09.2018, 14:02
masli, ок. Объясняте почему в Вашем коде нельзя использовать try-with-resources.
0
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789
27.09.2018, 14:25  [ТС]
Я нашел решение, оно хоть и громоздкое, но можно избежать использование finally.

Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Override
    public List<TranslitEntity> loadAllUserTranslits(Integer userId) {
 
        List<TranslitEntity> result = new ArrayList<TranslitEntity>();
 
        Connection connectionTmp = null;
 
        try (Connection connection = ConnectionPool.getPool().getConnection();
             PreparedStatement statement = connection.prepareStatement("SELECT * from translits " +
                     "WHERE user_id = ?");
 
             ) {
            connectionTmp = connection;
            statement.setInt(1, userId);
 
        try(ResultSet set = statement.executeQuery()){
            System.out.println("set - " + set);
            System.out.println();
            while (set.next()) {
                TranslitEntity entity = ResultSetConverter.createTranslitEntity(set);
                result.add(entity);
            }
        }
 
        } catch (SQLException e) {
            rollback(connectionTmp);
            throw new DaoException(e);
        }
 
        return result;
    }


Как видно, можно было выкрутиться вложенным оператором try-with-resources , а для того, чтобы можно было выполнить откат транзакции, тогда открытый ресурс connection, можно сохранить во временной переменной и ее использовать, чтобы вызвать откат транзакции, на текущем ресурсе.

Добавлено через 2 минуты
Цитата Сообщение от JIeIIIa Посмотреть сообщение
Объясняте почему в Вашем коде нельзя использовать try-with-resources.
Не знал как выполнить откат транзакции и как закрыть ResulSet.
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
27.09.2018, 14:42
masli, почему не так?
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public List<TranslitEntity> loadAllUserTranslits(Integer userId) {
 
        List<TranslitEntity> result = new ArrayList<TranslitEntity>();
 
        try (Connection connection = ConnectionPool.getPool().getConnection();
             PreparedStatement statement = connection.prepareStatement("SELECT * from translits " +
                     "WHERE user_id = ?");
        ) {
        
            statement.setInt(1, userId);
 
            try(ResultSet set = statement.executeQuery()){
                System.out.println("set - " + set);   
                System.out.println();
                while (set.next()) {
                    TranslitEntity entity = ResultSetConverter.createTranslitEntity(set);
                    result.add(entity);
                }
            } catch (SQLException e) {
               rollback(connection);
               throw new DaoException(e);
            }
 
        } catch (SQLException e) {
            throw new DaoException(e);
        }
 
        return result;
    }
0
52 / 18 / 11
Регистрация: 27.03.2013
Сообщений: 789
27.09.2018, 14:58  [ТС]
как я понимаю, если исключение "словится" в момент открытия PreparedStatement statement, тогда не нужно будет ничего "откатывать", а вот откат нужен, когда выполняется команда statement.executeQuery() ?

Добавлено через 1 минуту
Таким образом можно избежать использования временной переменной для ресурса connection?
0
958 / 577 / 136
Регистрация: 23.05.2012
Сообщений: 7,364
27.09.2018, 14:59
Лучший ответ Сообщение было отмечено masli как решение

Решение

Если не используются вложенные транзакции, то да.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.09.2018, 14:59
Помогаю со студенческими работами здесь

Как быть когда нужно вернуть NULL?
Как быть если нужно чтобы функция в некоторых условиях возвращала NULL, а не возвращаемый тип?

Google Play Services Sign In / com.google.android.gms.common.api.ApiException: 10
Пробую запустить простейший семпл для авторизации в Google Play Services, но всё время получаю одну и ту же ошибку Мой код полностью...

Тип void как возвращаемое значение функции: что он такое, зачем он нужен, где, когда и как его использовать?
Объясните пожалуйста про Void для оооочень далекого человека. Читаю книгу Шилдта, в принципе всё ясно, всё понимаю и пробую, но вот Void -...

Как быть в ситуации когда строка занимает не то место из-за внутреннего идентификатора?
Как быть в ситуации когда строка занимает не то место из-за внутреннего идентификатора? Заранее спасибо!

Когда я закрываю эту форму появляется множество ошибок, как быть?
При Window f = new Window(); f.ShowDialog(); // все хорошо, но 2 формы не могут быть активными при ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru