Spring Boot: Jdbc javax.net.ssl.SSLException: закрытие входящих сообщений перед получением close_notify однорангового узла

В настоящее время я изучаю больше о реализации JDBC и использовании баз данных в веб-приложении Spring Boot, и я обнаружил следующую трассировку стека, написанную в нижней части сообщения.

Я создал простую модель Employee и пытаюсь выполнить некоторый код базы данных в том же классе, в котором находится мой main (). Модель и основной класс - единственные два файла java, существующие во всем этом проекте. Я пытаюсь реализовать следующий код run (), который переопределяет код из интерфейса CommandLineRunner, но я не получаю журналы, которые должны появиться после log.info («Часть A:»):

log.info("Part A:")
employees.forEach(employee -> {log.info(employee.toString());
        log.info("part a");});

- Что я заметил:

Я заметил, что последняя строка журнала перед началом трассировки стека идет от: «Thread-1» вместо «main». Я думаю, это означает, что поток из другого места, кроме основного, обнаружил ошибку и закрыл соединение до того, как он должен нормально закрываться.

Кроме того, я думаю, что из-за того, что HikariPool закрыт до "peer close_notify", который, как я полагаю, относится к нормальному закрытию HikariPool, я не могу увидеть последний бит регистрации, который я все время пытался получить. Последний этап ведения журнала, который я хочу увидеть, - это запись сотрудника, который был добавлен в мою базу данных.

Последний бит регистрации, который я хочу увидеть, должен быть получен из этой строки кода:

employees.forEach(employee -> {log.info(employee.toString());
        log.info("part a");});

- На заметку:

Из-за этой строки в журнале я думал, что увижу сотрудника, вставленного в мою базу данных, но когда я запросил непосредственно в клиенте командной строки MySQL, он вернул пустой набор:

2018-11-03 21:08:35.362  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : rows affected: 1

Не понимаю, почему строка была затронута, когда ничего не было вставлено в базу данных.

Трассировка стека и журналы: (Вставленная ниже трассировка стека на самом деле повторяется еще несколько раз, но я вырезал ее для краткости.)

2018-11-03 21:08:32.997  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Starting JdbcTest1Application on KitKat with PID 2408 (C:\Users\Nano\Downloads\jdbc-test1\jdbc-test1\target\classes started by Nano in C:\Users\Nano\Downloads\jdbc-test1\jdbc-test1)
2018-11-03 21:08:33.003  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : No active profile set, falling back to default profiles: default
2018-11-03 21:08:33.770  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Started JdbcTest1Application in 1.024 seconds (JVM running for 1.778)
2018-11-03 21:08:33.770  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Creating tables
2018-11-03 21:08:33.770  INFO 2408 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2018-11-03 21:08:34.082  INFO 2408 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2018-11-03 21:08:35.135  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Inserting Baggins Hopkins
2018-11-03 21:08:35.362  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : rows affected: 1
2018-11-03 21:08:35.362  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Querying for employee
2018-11-03 21:08:36.065  INFO 2408 --- [           main] c.j.jdbctest1.JdbcTest1Application       : Part A:
2018-11-03 21:08:36.065  INFO 2408 --- [       Thread-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
Sat Nov 03 21:08:36 KST 2018 WARN: Caught while disconnecting...

EXCEPTION STACK TRACE:



** BEGIN NESTED EXCEPTION ** 

javax.net.ssl.SSLException
MESSAGE: closing inbound before receiving peer's close_notify

STACKTRACE:

javax.net.ssl.SSLException: closing inbound before receiving peer's close_notify
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:129)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:255)
    at java.base/sun.security.ssl.SSLSocketImpl.shutdownInput(SSLSocketImpl.java:645)
    at java.base/sun.security.ssl.SSLSocketImpl.shutdownInput(SSLSocketImpl.java:624)
    at com.mysql.cj.protocol.a.NativeProtocol.quit(NativeProtocol.java:1312)
    at com.mysql.cj.NativeSession.quit(NativeSession.java:182)
    at com.mysql.cj.jdbc.ConnectionImpl.realClose(ConnectionImpl.java:1750)
    at com.mysql.cj.jdbc.ConnectionImpl.close(ConnectionImpl.java:720)
    at com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:135)
    at com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:441)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)


** END NESTED EXCEPTION **

Код Java:

@SpringBootApplication
public class JdbcTest1Application implements CommandLineRunner {
    private static final Logger log = LoggerFactory.getLogger(JdbcTest1Application.class);

    @Autowired
    JdbcTemplate jdbcTemplate;

    public static void main(String[] args) {
        SpringApplication.run(JdbcTest1Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        log.info("Creating tables");

        jdbcTemplate.execute("DROP TABLE IF EXISTS employees");
        jdbcTemplate.execute("CREATE TABLE employees (emp_id int, name varchar(100), role varchar(100), status varchar(100))");

        log.info("Inserting Baggins Hopkins");
        int rowsAffected = jdbcTemplate.update("INSERT INTO EMPLOYEE(EMP_ID, NAME, ROLE, STATUS)"
                + " VALUES(1,'Baggins Hopkins','thief','WORKING')");
        log.info("rows affected: "+ Integer.toString(rowsAffected));
        log.info("Querying for employee");
        String sql = "SELECT emp_id,name,role,status FROM employees";
        List<Employee> employees = jdbcTemplate.query(sql,(rs, rowNum)-> 
        new Employee(rs.getInt("emp_id"), rs.getString("name"),
                rs.getString("role"),Status.valueOf(rs.getString("status"))));
        log.info("Part A:");
        employees.forEach(employee -> {log.info(employee.toString());
            log.info("part a");});

    }
}

Также на всякий случай я вставил этот код из application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/employee_database
spring.datasource.username=employee
spring.datasource.password=employee
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

С помощью какого JDK можно воспроизвести эту проблему?

Jason Young 21.02.2019 18:49
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
43
1
82 556
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

SSL-соединение с базой данных не работает, попробуйте изменить URL-адрес источника данных на:

spring.datasource.url=jdbc:mysql://localhost:3306/employee_database?useSSL=false

Привет, спасибо за ответ, но я получаю сообщение об ошибке: java.sql.SQLNonTransientConnectionException: получение открытого ключа запрещено

Dup Park 05.11.2018 03:51

В соединителе mysql 8.0.13 этот параметр был устаревшим. Добавление? SslMode = DISABLED вместо этого решило проблему для меня.

schrom 08.11.2018 08:43

Я получал ту же ошибку при попытке подключиться к jdbc с помощью команды Liquibase (Liquibase: update) и после добавления в url? UseSSL = false в файле * .properties работает отлично. Это должен быть принятый вопрос, пожалуйста.

bishop 29.01.2019 12:34

@bishop Я почти уверен, что спрашивающий выберет ответ, решивший его проблему, как принятый. Несмотря на то, что этот ответ не принят в качестве ответа, он по-прежнему признан самым высоким и остается выше моего, чтобы другие могли проверить его первыми, поэтому я думаю, что оставлю свой ответ принятым. Другими словами, у меня это не сработало, и я тот, кто спросил, так что нет, это не будет принятым ответом. Пока он остается на вершине и набирает наибольшее количество голосов, я не вижу большой проблемы.

Dup Park 30.01.2019 07:06

Это обходной путь только для целей тестирования, а не решение. См. Ответ @Michael Técourt.

Jason Young 21.02.2019 18:50
Ответ принят как подходящий

На решение этой проблемы у меня ушло около трех дней.

(Обновлено: это обходной путь для тестирования, а не на самом деле решение.)

Сначала я начал решать проблему с попытки настроить собственный SSL для mysql, и потратил на это довольно много часов. Прошло слишком много времени, пока я не понял, что настройка связана с Cmake и C++, что заставило меня сдаться. Это было очень неприятно. Однако я не сдался и попытался полностью отключить SSL с помощью метода, который не был найден. И в конце концов я нашел метод. Вот:

  1. Вы должны использовать старый пароль для MySQL. Устаревший пароль - это способ аутентификации MySQL в версии 5.7x.

Снова откройте установщик MySQL и измените настройки сервера MySQL. Когда вы попадете туда, вы увидите этот экран:

Экран, на который вы должны попасть

You might get some errors when reaching the final stage of the reconfiguration:

I had problems at the final stage I had no idea how to fix so I uninstalled MySQL altogether. I use windows. I deleted the MySQL project root directory from Program Files to uninstall MySQL. I also deleted the databases saved in Program Data (a hidden folder in the C Drive) because I wanted to start afresh(WARNING: this will delete all your previously saved data!). Uninstalling MySQL from the control panel might not be enough to completely erase MySQL from your computer.

  1. Удалите все файлы * .pem в C: \ ProgramData \ MySQL \ MySQL Server 8.0 \ Data. (или переместите его в другое место, как я и сделал)

You might not see ProgramData in the C Drive. That is because it is a hidden folder. In order to see hidden folders:

search for folder options in the control panel.

Go to view.

Under 'Advanced settings' and under 'Hidden files and folders' of that, click "Show hidden files, folders, and drives."

  1. Перейдите в C: \ ProgramData \ MySQL \ MySQL Server 8.0 и откройте my.cnf (или my.ini). Добавьте следующую строку после [mysqld]:

ssl=0

Тогда сохраните. Теперь он должен работать.

Использованная литература:

  1. https://community.atlassian.com/t5/Confluence-questions/MySQL-Public-Key-Retrieval-is-not-allowed/qaq-p/778956
  2. https://scalegrid.io/blog/configuring-and-managing-ssl-on-your-mysql-server/

Означает ли это также "отключить" SSL при установке ssl = 0? Я думаю, что в большинстве случаев - особенно в коммерческом мире - это нежелательная настройка.

Lei Z 21.01.2021 14:52

Предупреждение выглядит как ошибка драйвера MySQL с Java 11 и включенным SSL: https://bugs.mysql.com/bug.php?id=93590
Отключение шифрования из-за драйвера предупреждение - плохая идея.

Ваша проблема с вставкой больше похожа на классическую проблему транзакции, хотя я сомневаюсь, что она связана с предупреждением SSL.

Похоже, что такая же ошибка существует для Java 8.0.27x. Я нашел его на 8.0.272.hs-adpt (через sdkman) и 8.0.275-amzn. 8.0.265.fx-librca была последней версией через sdkman, которая не ошибалась с драйвером MySQL 8.0.21.

randy 18.12.2020 18:22

У меня была эта проблема, и я решил использовать Решение Carrier Pigeon Protocol, пока случайно не решил ее, обновив Tomcat с версии 9.0.12 до 9.0.16.

К сожалению, я получаю его и для 9.0.16.

Gunith D 06.04.2019 08:42

Я думал, что у меня это работает, когда я опубликовал этот ответ, но сейчас я не уверен. В последнее время я использую пул соединений с Tomcat's PoolСвойства. Это позволяет мне устанавливать соединение, не отключая SSL, но теперь у меня есть предупреждение об утечке памяти, которое я еще не удосужился устранить.

Jack J 06.04.2019 13:23

Я тоже столкнулся с той же проблемой. если вы посмотрите на трассировку стека, ясно сказано, что делать -

Sat Mar 16 09:00:01 IST 2019 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. 
You need either to explicitly disable SSL by setting **useSSL=false**, or set **useSSL=true** and provide truststore for server certificate verification.

поэтому после отключения ssl путем внесения изменений в URL-адрес источника данных проблема была решена -

spring.datasource.url=jdbc:mysql://localhost:3306/security?useSSL=false

Я столкнулся с аналогичной проблемой, когда обновил версию Java на своем сервере до 11 с 8.

Весенняя загрузка запускала поддерживающий Java 11 начиная с версии 2.1. Поэтому убедитесь, что зависимости вашего проекта также обновлены соответствующим образом. Это актуально для этого ответа, поскольку SpringBoot также влияет на соединитель MySQL, ядро ​​Hibernate и другие зависимости.

Невозможность подключения к БД приводила к еще нескольким ошибкам NoClassDefFoundErrors. Поэтому убедитесь, что вы решили эту проблему, прежде чем искать другие ошибки.

Пример зависимости pom для стартера SpringBoot

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.12.RELEASE</version>
    <relativePath />
</parent>

Надеюсь, это кому-то поможет.

Попробуйте использовать следующий URL. Как они предложили, используйте useSSL = false. Кроме того, не забудьте использовать <& amp> вместо просто &, когда у вас есть несколько свойств, определенных в вашем URL-адресе.

jdbc:mysql://localhost:3306/TestDB?serverTimezone=PST&amp;useSSL=false

Я тоже столкнулся с той же проблемой

Но затем я обновил версию mysql-connector-java с 5.1.46 до 8.0.20 и изменил com.mysql.jdbc.Driver на com.mysql.cj.jdbc.Driver это решило мою проблему

Моя проблема сходства в искре, Я решаю проблему с помощью java-версии с 'openjdk версии "1.8.0_275" "на" openjdk версии "1.8.0_265"', надеюсь быть вам полезным

Это сработало для меня

   <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
        <version>8.0.20</version>
    </dependency>

Это тоже сработало для меня. Похоже, что использование последней версии (я использую 8.0.23) может решить проблему.

Lei Z 21.01.2021 15:23

У меня это тоже сработало, но не знаю, почему? Это как-то связано с самозаверяющими сертификатами в более старых версиях?

ephemeralCoder 01.06.2021 20:04

Моя аналогичная проблема в коте, пытающемся подключиться через ssl к Aurora mysql (AWS)

Я решил проблему, обновив версию драйвера с mysql-connector-java-5.1.40.jar до mysql-connector-java-5.1.49.jar и установив корневой ЦС в ceacerts:

keytool -import -trustcacerts -file rds-ca-2019-root.pem -keystore /<your_java_home>/lib/security/cacerts

Надеюсь, ты пригодишься

Ссылка на сертификат AWS: docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/…

Ruimán 22.06.2021 12:28

Это была именно та проблема, с которой я столкнулся. Как только я обновил mysql-коннектор (вместе с соответствующим сертификатом), все заработало нормально.

Marcus 16.09.2021 05:48

Другие вопросы по теме