web-dev-qa-db-fra.com

Spring Boot: Jdbc javax.net.ssl.SSLException: fermeture en entrée avant de recevoir close_notify

J'apprends actuellement davantage sur la mise en œuvre de JDBC et l'utilisation de bases de données dans une application Web Spring Boot. J'ai rencontré le suivi de pile suivant, écrit au bas de l'article.

J'ai créé un modèle simple Employee et j'essaie d'exécuter du code de base de données sur la même classe que celle dans laquelle se trouve mon main (). Le modèle et la classe main sont les deux seuls fichiers Java existant dans l'ensemble du projet. J'essaie d'implémenter le code run () suivant qui remplace celui de l'interface, CommandLineRunner, mais je ne reçois pas les journaux qui devraient venir après log.info ("Part A:"):

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

- Choses j'ai remarqué:

J'ai remarqué que la dernière ligne du journal avant le début de la trace de pile provient de "Thread-1" au lieu de "main". Je pense que cela signifie qu'un thread d'un autre endroit que le principal a rencontré une erreur et une connexion fermée avant quand il devrait se fermer normalement.

De plus, je pense que, parce que HikariPool a été fermé avant "peer close_notify" , ce qui, je suppose, fait référence à la fermeture normale de HikariPool, je ne suis pas en mesure de voir le dernier morceau de bois que j'ai essayé de me procurer. Le dernier élément de journalisation que je souhaite voir est la journalisation de l'employé qui a été inséré dans ma base de données.

Le dernier bit de journalisation que je veux voir doit être obtenu à partir de cette ligne de code:

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

- Choses à noter:

En raison de cette ligne dans le journal, j'ai pensé voir l'employé être inséré dans ma base de données, mais lorsque j'ai interrogé directement le client en ligne de commande MySQL, il a renvoyé un ensemble vide:

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

Je ne comprends pas pourquoi une ligne a été affectée alors que rien n’a été inséré dans la base de données .

Le stacktrace et les logs: (Le stacktrace collé ci-dessous se répète plusieurs fois mais je l’ai coupé par souci de concision.)

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 **

Le code 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");});

    }
}

Aussi, juste au cas où cela serait important, j'ai collé ce code à partir de 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
5
Dup Park

Pour résoudre ce problème, il m'a fallu environ trois jours.

Au début, j’ai commencé à résoudre le problème en essayant de configurer mon propre SSL pour mysql, et j’y ai consacré pas mal d’heures. Trop de temps s’est écoulé jusqu’à ce que je me rende compte que la configuration doit être faite avec Cmake et C++, ce qui m’a fait abandonner. C'était très frustrant. Cependant, je n’ai pas abandonné et j’ai essayé de désactiver SSL entièrement par une méthode qui n’a pas été trouvée. Et j'ai finalement trouvé la méthode. C'est ici:

  1. Vous devez utiliser le mot de passe hérité pour MySQL. Le mot de passe hérité est le moyen utilisé par MySQL pour authentifier les choses dans la version 5.7x. 

Ouvrez à nouveau le programme d'installation MySQL et reconfigurez les paramètres du serveur MySQL . Lorsque vous y arriverez, cet écran s'affichera:

L'écran auquel vous devez accéder

Vous pourriez avoir quelques erreurs lorsque vous atteignez la dernière étape de la reconfiguration:

Ayant eu des problèmes au stade final, je ne savais pas comment résoudre le problème, j'ai donc complètement désinstallé MySQL. J'utilise des fenêtres. J'ai supprimé le répertoire racine du projet MySQL de Program Files pour désinstaller MySQL. J'ai également supprimé les bases de données enregistrées dans Program Data (un dossier caché dans le lecteur C) car je souhaitais tout recommencer (AVERTISSEMENT: toutes vos données précédemment enregistrées seront supprimées!). Désinstaller MySQL à partir du panneau de configuration risque de ne pas suffire à effacer complètement MySQL de votre ordinateur.

  1. Supprimez tous les fichiers * .pem dans C:\ProgramData\MySQL\MySQL Server 8.0\Data. (ou déplacez-le ailleurs, c'est ce que j'ai fait)

Vous ne verrez peut-être pas ProgramData dans le lecteur C. C'est parce que c'est un dossier caché. Pour voir les dossiers cachés: 

rechercher des options de dossier dans le panneau de configuration.

Allez voir.

Sous "Paramètres avancés" et sous "Fichiers et dossiers cachés", cliquez sur "Afficher les fichiers, les dossiers et les lecteurs cachés".

  1. Accédez à C:\ProgramData\MySQL\MySQL Server 8.0 et ouvrez my.cnf (ou my.ini). Ajoutez la ligne suivante après [mysqld]:

ssl = 0

Puis enregistrez. Cela devrait fonctionner maintenant.

EDIT: Je me suis rendu compte que ma syntaxe SQL pour la requête de mise à jour était fausse. Je me suis inséré dans la mauvaise table. Je pense que l'insertion dans la base de données a peut-être encore fonctionné, que le problème SSLException ait été résolu ou non. (Je ne suis pas sûr cependant ...)

Références: 

  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/
1
Dup Park

La connexion SSL à la base de données échoue. Essayez de modifier l'URL de votre source de données en: 

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

L'avertissement ressemble à un bogue de pilote MySQL avec Java 11 et SSL activé: https://bugs.mysql.com/bug.php?id=93590
Désactiver le chiffrement à cause d'un pilote warning est une mauvaise idée.

Votre problème d'insertion ressemble plus à un problème de transaction classique, cependant, je doute qu'il soit lié à l'avertissement SSL.

2
Michael Técourt