powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / guava UncheckedExecutionException
14 сообщений из 14, страница 1 из 1
guava UncheckedExecutionException
    #39371707
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
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.
WARNING: Exception thrown by removal listener
com.google.common.util.concurrent.UncheckedExecutionException: java.lang.NullPointerException
        at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2207)
        at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
        at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4790)
        at main.DB.writeUserDownloadLater(DB.java:116)
        at main.cache.Session.close(Session.java:137)
        at main.DownloadMeter.lambda$main$0(DownloadMeter.java:67)
        at com.google.common.cache.LocalCache.processPendingNotifications(LocalCache.java:1960)
        at com.google.common.cache.LocalCache$Segment.runUnlockedCleanup(LocalCache.java:3475)
        at com.google.common.cache.LocalCache$Segment.postWriteCleanup(LocalCache.java:3451)
        at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2277)
        at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2201)
        at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
        at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4790)
        at main.DownloadMeter.main(DownloadMeter.java:137)
Caused by: java.lang.NullPointerException
        at com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5268)
        at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5151)
        at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5190)
        at main.DB.lambda$writeUserDownloadLater$0(DB.java:127)
        at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4793)
        at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3542)
        at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2323)
        at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2286)
        at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2201)
        ... 13 more

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
sessions = CacheBuilder
        .newBuilder()
        .initialCapacity(30000)
        .maximumSize(5000000)
        .expireAfterAccess(session_ttl, TimeUnit.SECONDS)
        .removalListener((RemovalListener<String, Session>) notification -> {
            Session session = notification.getValue();
            if (session != null) {
                logger.debug("Close session: " + notification.getKey());
                // ------------- > line 67
                session.close();
            }
        })
        .build();

...
...

//  ------------- > line 137
Session session = sessions.get(jsonMessage.get("id").getAsString(), () -> new Session(

));



Пока один поток закрывает сессию, другому потоку она понадобилась, если я все правильно понимаю.
И как такое решается?
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371719
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
writeUserDownloadLater не вижу в коде.
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371751
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то я туда не догадался загнянуть, а там тоже работа с кэшем:

Код: 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.
public class DB {
    ...
    private static Cache<String, String> downloadsWithUserFileRelations = CacheBuilder
            .newBuilder()
            .maximumSize(1000000)
            .expireAfterAccess(15, TimeUnit.MINUTES)
            .build();
    ...
    ...
    public void writeUserDownloadLater(Session session) {
        try {
            // ------------ > line 116
            String user_file_id = downloadsWithUserFileRelations.get(session.getId(), () -> {
                downloadToUserFileStmt.setString(1, session.getId());
                ResultSet resultSet = downloadToUserFileStmt.executeQuery();
                if (!resultSet.next()) {
                    return null;
                }
                return resultSet.getString("user_file_id");
            });

            ...
            ...
        } catch (ExecutionException e) {
            DownloadMeter.logger.error("Execution exception", e);
        }
    }
}



Т.е. в removal listener был запрос к кэшу как раз, ну и я кажется понял суть проблемы.
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371756
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Т.е. тут NullPointerException вылетело, потому что session уже деинициализирована?
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371763
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Исключение всегда одно и то же? JDBC Connection случайно между потоками не шарится? Какая версия драйвера?
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371767
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettТ.е. тут NullPointerException вылетело, потому что session уже деинициализирована?
NPE вылетел в ResultSet драйвера MySQL. Где-то косяк работы с JDBC. Session к этому прямого отношения не имеет.
Как создаются и используются downloadToUserFileStmt и его Connection из указанного кода не видно.
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371860
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подключение к БД одно, downloadToUserFileStmt - создается после коннекта к БД.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
testCompileClasspath - Compile classpath for source set 'test'.
+--- org.apache.activemq:activemq-all:5.11.+ -> 5.11.4
+--- mysql:mysql-connector-java:5.1.+ -> 5.1.40
+--- com.google.code.gson:gson:2.+ -> 2.8.0
+--- com.google.guava:guava:19.+ -> 19.0
+--- org.mongodb:mongo-java-driver:2.13.+ -> 2.13.3
+--- commons-cli:commons-cli:1.3.+ -> 1.3.1
+--- org.apache.logging.log4j:log4j-api:2.+ -> 2.7
+--- org.apache.logging.log4j:log4j-core:2.+ -> 2.7
|    \--- org.apache.logging.log4j:log4j-api:2.7
+--- org.apache.commons:commons-lang3:3.+ -> 3.5
\--- junit:junit:4.+ -> 4.12
     \--- org.hamcrest:hamcrest-core:1.3

Т.е. надо пулл коннектов использовать?
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371881
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettТ.е. надо пулл коннектов использовать?
Нужно использовать 1 JDBC объект на каждый поток и не шарить их между потоками. А пул это у вас будет или что-то ещё, это уже другой вопрос. А тут, не понятно где соединение, не понятно откуда Statement, не ясно где оно всё закрывается. Бедлам.
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371919
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В PHP таких проблем не было (всегда жеж один поток), поэтому даже не подумал о работе одного соединения в многопоточной среде. Сессии тысячи и на каждую держать коннект не получится. Открывать на каждую запись тоже подумалось не лучшим вариантом.

Поизучал вопрос, сделал так:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    private static final BasicDataSource dataSource = new BasicDataSource();

    static {
        Properties properties = Properties.getInstance();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl(properties.getProperty("db_uri"));
        dataSource.setUsername(properties.getProperty("db_user"));
        dataSource.setPassword(properties.getProperty("db_password"));
    }

    public void touchDownload(String id) {
        try (
                PreparedStatement updateDownloadStmt = dataSource.getConnection().prepareStatement(
                        "UPDATE fh_download SET date_end = CURRENT_TIMESTAMP WHERE unique_key = ?"
                );
        ) {
            updateDownloadStmt.setString(1, id);
            updateDownloadStmt.executeUpdate();
        } catch (SQLException e) {
            DownloadMeter.logger.error("SQL error", e);
        }
    }



Единственное, что смущает, что Statement создается каждый раз, но если я правильно понял из первого беглого прочтения доки, то он все таки кэшируется?
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371922
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тем не менее с драйвером MongoDB таких проблем вроде не замечено, один коннект на все потоки работает без нареканий.
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371936
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettТем не менее с драйвером MongoDB таких проблем вроде не замечено, один коннект на все потоки работает без нареканий.
Весь софт работает одинаково. Это отличное предположение, на которое стоит опираться при кодировании. Плевать на JDBC спеку.
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371953
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В доке говорят, что можно шарить между потоками:

авторThe MongoClient class is designed to be thread safe and shared among threads. Typically you create only 1 instance for a given database cluster and use it across your application.
http://mongodb.github.io/mongo-java-driver/2.13/getting-started/quick-tour/
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39371966
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hett,

Работать с MySQL через JDBC и руководствоваться при этом докой по MongoDB это пять.
...
Рейтинг: 0 / 0
guava UncheckedExecutionException
    #39372025
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я не изучал доки досконально. Конкретно по работе с потоками стал разбирать только когда с проблемой столкнулся. Про монгу отписался по мере прочтения доки, так как заподозрил что и там подобная проблема есть.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / guava UncheckedExecutionException
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]