276 votes

Résolution d'un "échec de la liaison de communication" avec JDBC et MySQL

J'essaie de me connecter au serveur MySQL local mais j'obtiens toujours une erreur.

Voici le code.

public class Connect {

    public static void main(String[] args) {
        Connection conn = null;

        try {
            String userName = "myUsername";
            String password = "myPassword";

            String url = "jdbc:mysql://localhost:3306/myDatabaseName";
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            conn = DriverManager.getConnection(url, userName, password);
            System.out.println("Database connection established");
        } catch (Exception e) {
            System.err.println("Cannot connect to database server");
            System.err.println(e.getMessage());
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                    System.out.println("Database Connection Terminated");
                } catch (Exception e) {}
            }
        }
    }
}

et les erreurs :

Cannot connect to database server
Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:344)
        at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2333)
        at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2370)
        at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2154)
        at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:792)
        at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
        at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:381)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305)
        at java.sql.DriverManager.getConnection(DriverManager.java:582)
        at java.sql.DriverManager.getConnection(DriverManager.java:185)
        at Connect.main(Connect.java:16)
    Caused by: java.net.ConnectException: Connection refused
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
        at java.net.Socket.connect(Socket.java:529)
        at java.net.Socket.connect(Socket.java:478)
        at java.net.Socket.<init>(Socket.java:375)
        at java.net.Socket.<init>(Socket.java:218)
        at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:257)
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:294)
        ... 15 more

J'ai défini le classpath, je me suis assuré que l'option skip network de my.cnf était commentée.

la version de java est 1.2.0_26 (64 bit) mysql 5.5.14 connecteur mysql 5.1.17

Je me suis assuré que l'utilisateur avait accès à ma base de données.

7 votes

Notez le CausedBy en bas. Le serveur SQL n'a jamais accepté la connexion. Que se passe-t-il si l'on fait (à partir d'une ligne de commande) telnet localhost 3306 ? Le serveur mySQL fonctionne-t-il ?

0 votes

Vérifiez ce poste. Cela pourrait vous aider : stackoverflow.com/questions/15949/

2 votes

Problème résolu, j'ai ajouté une entrée d'adresse de reliure à my.cnf.

495voto

Soheil Points 890

J'ai eu le même problème dans deux de mes programmes. Mon erreur était la suivante :

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.

J'ai passé plusieurs jours à résoudre ce problème. J'ai testé de nombreuses approches qui ont été mentionnées sur différents sites web, mais aucune d'entre elles n'a fonctionné. Finalement, j'ai modifié mon code et j'ai trouvé la cause du problème. Je vais essayer de vous parler de différentes approches et résumez-les ici .

Alors que je cherchais sur internet la solution à cette erreur, j'ai découvert que il existe de nombreuses solutions qui ont fonctionné pour au moins une personne, mais d'autres disent que cela ne fonctionne pas pour elles ! pourquoi il y a plusieurs approches de cette erreur ? Il semble cette erreur peut se produire généralement lorsqu'il y a un problème de connexion au serveur . Le problème est peut-être dû à une mauvaise chaîne de requête ou à un trop grand nombre de connexions à la base de données.

Je vous suggère donc d'essayer toutes les solutions une par une et de ne pas abandonner !

Voici les solutions que j'ai trouvées sur internet et pour chacune d'entre elles, il y a au moins une personne dont le problème a été résolu avec cette solution.

Conseil : Pour les solutions qui nécessitent de modifier les paramètres de MySQL, vous pouvez vous référer aux fichiers suivants :

  • Linux : /etc/mysql/my.cnf o /etc/my.cnf (selon la distribution Linux et le paquet MySQL utilisé)

  • Les fenêtres : C:\**ProgramData**\MySQL\MySQL Server 5.6\my.ini (Remarquez que c'est ProgramData, pas Program Files)

Voici les solutions :

  • en changeant bind-address attribut :

    Décommenter bind-address ou le changer pour l'une des IP suivantes :

     bind-address="127.0.0.1"

    o

     bind-address="0.0.0.0"
  • en commentant "skip-networking".

    S'il existe un skip-networking dans votre fichier de configuration MySQL, mettez-la en commentaire en ajoutant # au début de cette ligne.

  • modifier "wait_timeout" et "interactive_timeout".

    Ajoutez ces lignes au fichier de configuration de MySQL :

    [wait_timeout][1] = *number*
    
    interactive_timeout = *number*
    
    connect_timeout = *number*
  • Vérifiez que Java ne traduit pas 'localhost' en [:::1] au lieu de [127.0.0.1].

    Puisque MySQL reconnaît 127.0.0.1 ( IPv4 ) mais pas :::1 ( IPv6 )

    Cela peut être évité en utilisant l'une des deux approches suivantes :

    1. Dans la chaîne de connexion, utilisez 127.0.0.1 au lieu de localhost pour éviter localhost qui est traduit en :::1

    2. Exécutez java avec l'option -Djava.net.preferIPv4Stack=true pour forcer java à utiliser IPv4 au lieu de IPv6 . Sous Linux, cela peut également être réalisé en exécutant (ou en plaçant à l'intérieur de) /etc/profile :

       export _JAVA_OPTIONS="-Djava.net.preferIPv4Stack=true"
  • vérifier les paramètres du proxy du système d'exploitation, les pare-feu et les programmes anti-virus

    Assurez-vous que le pare-feu ou le logiciel anti-virus ne bloque pas le service MySQL.

    Arrêter temporairement iptables sur linux. Si iptables est mal configuré, il peut autoriser l'envoi de paquets tcp vers le port mysql, mais bloquer le retour des paquets tcp sur la même connexion.

     # Redhat enterprise and CentOS
     systemctl stop iptables.service
     # Other linux distros
     service iptables stop

    Arrêtez les logiciels anti-virus sur Windows.

  • modifier la chaîne de connexion

    Vérifiez votre chaîne de requête. Votre chaîne de connexion devrait être quelque chose comme ceci :

    dbName = "my_database";
    dbUserName = "root";
    dbPassword = "";
    String connectionString = "jdbc:mysql://localhost/" + dbName + "?user=" + dbUserName + "&password=" + dbPassword + "&useUnicode=true&characterEncoding=UTF-8";

Assurez-vous que vous n'avez pas d'espaces dans votre chaîne. Toute la chaîne de connexion doit être continue sans aucun caractère d'espace.

Essayez de remplacer "localhost" par l'adresse de bouclage 127.0.0.1. Essayez également d'ajouter le numéro de port à votre chaîne de connexion, comme :

String connectionString = "jdbc:mysql://localhost:3306/my_database?user=root&password=Pass&useUnicode=true&characterEncoding=UTF-8";

Habituellement, le port par défaut de MySQL est 3306.

N'oubliez pas de changer le nom d'utilisateur et le mot de passe par le nom d'utilisateur et le mot de passe de votre serveur MySQL.

  • mettez à jour votre fichier de bibliothèque de pilotes JDK
  • tester différents JDK et JRE (comme JDK 6 et 7)
  • ne pas changer max_allowed_packet

" max_allowed_packet "est une variable du fichier de configuration de MySQL qui indique la taille maximale des paquets, et non le nombre maximal de paquets. Elle ne vous aidera donc pas à résoudre cette erreur.

  • changer la sécurité de tomcat

changer TOMCAT6_SECURITY=yes en TOMCAT6_SECURITY=no

  • utiliser la propriété validationQuery

utiliser validationQuery="select now()" pour s'assurer que chaque requête a des réponses

  • AutoReconnect

Ajoutez ce code à votre chaîne de connexion :

&autoReconnect=true&failOverReadOnly=false&maxReconnects=10

Bien qu'aucune de ces solutions n'ait fonctionné pour moi, je vous suggère de les essayer. Car il y a des gens qui ont résolu leur problème en suivant ces étapes.

Mais qu'est-ce qui a résolu mon problème ?

Mon problème était que j'avais beaucoup de SELECTs sur la base de données. À chaque fois, je créais une connexion, puis je la fermais. Bien que je fermais la connexion à chaque fois, le système faisait face à de nombreuses connexions et me donnait cette erreur. Ce que j'ai fait, c'est que j'ai défini ma variable de connexion comme une variable publique (ou privée) pour toute la classe et je l'ai initialisée dans le constructeur. Ensuite, à chaque fois, j'ai juste utilisé cette connexion. Cela a résolu mon problème et a également augmenté ma vitesse de façon spectaculaire.

Conclusion# Il n'y a pas de moyen simple et unique de résoudre ce problème. Je vous suggère de réfléchir à votre propre situation et de choisir les solutions ci-dessus. Si vous rencontrez cette erreur au début du programme et que vous n'êtes pas en mesure de vous connecter à la base de données, il se peut que vous ayez un problème dans votre chaîne de connexion. Mais si vous rencontrez cette erreur après plusieurs interactions réussies avec la base de données, le problème peut provenir du nombre de connexions et vous pouvez penser à modifier "wait_timeout" et d'autres paramètres MySQL ou réécrire votre code de manière à réduire le nombre de connexions.

3 votes

J'ai ajouté seulement wait_timeout, référencé à dev.mysql.com/doc/refman/5.1/fr/

0 votes

Où sont les variables TOMCAT6_SECURITY y validationQuery ? Merci !

0 votes

Ce lien ici semble également être très utile : supermanhamuerto.com/

9voto

Kevin Lawrence Points 546

Fixer le bind-address à l'IP du réseau du serveur au lieu de l'IP par défaut de localhost, et la définition des privilèges sur mon utilisateur a fonctionné pour moi.

mon.cnf :

bind-address = 192.168.123.456

Console MySql :

GRANT ALL PRIVILEGES ON dbname.* to username@'%' IDENTIFIED BY 'password';

1 votes

Ou utiliser 0.0.0.0 pour toutes les interfaces...

0 votes

Réponse a fonctionné pour moi, pouvez-vous décrire ce que fait @'%' signifie dans la directive mysql ci-dessus ?

0 votes

Bind-address = 0.0.0.0 a fonctionné pour moi.

5voto

Renann Points 18

Je viens de rencontrer le même problème. Cela s'est produit parce que le démon MySQL était lié à l'IP de la machine, ce qui est nécessaire pour établir la connexion avec un utilisateur qui a la permission de se connecter à @votre_machine. Dans ce cas, l'utilisateur doit avoir la permission de se connecter USER_NAME@MACHINE_NAME_OR_IP.

Je voulais un accès à distance à ma machine, j'ai donc modifié mon fichier my.cnf de la façon suivante

bind-address = MY_IP_ADDRESS

A

bind-address = 0.0.0.0

Ce qui permettra à un utilisateur de localhost ET même de l'extérieur (dans mon cas) de se connecter à l'instance. Les deux permissions ci-dessous fonctionneront si vous liez le MySQL à 0.0.0.0 :

USER_NAME@MACHINE_NAME_OR_IP

USER_NAME@localhost

3voto

fuoco Points 21

Dans mon cas, il s'agissait d'un délai d'inactivité, qui a provoqué l'interruption de la connexion sur le serveur. La connexion est restée ouverte, mais n'a pas été utilisée pendant une longue période. Dans ce cas, un redémarrage du client fonctionne, et je pense qu'une reconnexion fonctionnera également.

Une bonne solution est d'avoir un démon/service qui envoie un ping à la connexion de temps en temps.

3voto

devdanke Points 509

Comme le dit la réponse détaillée ci-dessus, cette erreur peut être causée par de nombreuses choses.

J'ai eu ce problème aussi. Ma configuration était Mac OSX 10.8, utilisant une VM VirtualBox gérée par Vagrant d'Ubuntu 12.04, avec MySQL 5.5.34.

J'avais correctement configuré la redirection de port dans le fichier de configuration de Vagrant. Je pouvais me connecter à l'instance MySQL à la fois depuis mon Mac et depuis la VM. Je savais donc que le démon MySQL fonctionnait et était accessible. Mais lorsque j'ai essayé de me connecter via JDBC, j'ai obtenu l'erreur "Communications link failure".

Dans mon cas, le problème a été résolu en modifiant le fichier /etc/mysql/my.cnf. Plus précisément, j'ai commenté la ligne "#bind-address=127.0.0.1".

0 votes

Où avez-vous changé cela ? Host ou Vagrant MySql ?

0 votes

J'ai effectué le changement de configuration dans la VM invitée, où MySQL était exécuté. Je ne voulais pas que MySQL tourne directement sur mon Mac, j'ai donc utilisé une VM.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X