Tag Archives: Communications link failure

Fix “Communications link failure” in Java applications with MySQL

You may have problems connecting to MySQL from Java applications using Connector/J (the Java connector for MySQL) after upgrading/migrating MacPorts to a newer version. It happened to me after updating Mac OS X to El Capitan and upgrading MacPorts to work with it. Everything worked fine with phpMyAdmin and other applications using PHP but Java applications wouldn’t connect:

Exception in thread "main" java.lang.IllegalStateException: Cannot connect the database!
	at Main.main(Main.java:19)
Caused by: 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:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
	at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:983)
	at com.mysql.jdbc.MysqlIO.(MysqlIO.java:339)
	at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2252)
	at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2285)
	at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2084)
	at com.mysql.jdbc.ConnectionImpl.(ConnectionImpl.java:795)
	at com.mysql.jdbc.JDBC4Connection.(JDBC4Connection.java:44)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
	at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:400)
	at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:327)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:247)
	at Main.main(Main.java:16)
Caused by: java.net.ConnectException: Connection refused
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:214)
	at com.mysql.jdbc.MysqlIO.(MysqlIO.java:298)
	... 15 more

You can test a simple connection in Java with this code in a file named Main.java:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Main {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/database_name";
        String username = "username";
        String password = "password";

        System.out.println("Connecting database...");

        try (Connection connection = DriverManager.getConnection(url, username, password)) {
            System.out.println("Database connected!");
        } catch (SQLException e) {
            throw new IllegalStateException("Cannot connect the database!", e);
       }
    }
}

And running it like this (you’ll have to download the Java MySQL connector and place it in the same path with the .java file):

$ javac Main.java
$ java -cp .:./mysql-connector-java-5.1.37-bin.jar Main

I could connect to MySQL databases from the console using mysql so my server was running. I checked the usual configurations in my.cnf and didn’t see nothing wrong. The binding address was correct (it was 0.0.0.0 so connections from any IP could be done) and the socket file was also fine.

# Use default MacPorts settings
!include /opt/local/etc/mysql55/macports-default.cnf

[client]
port            = 3306
socket          = /opt/local/var/run/mysql55/mysqld.sock

[mysqld]
port            = 3306
socket          = /opt/local/var/run/mysql55/mysqld.sock
bind-address    = 0.0.0.0
max_allowed_packet = 256M

And then I saw it. Look at the include line. The problem was that the /opt/local/etc/mysql55/macports-default.cnf file in that include had been rewritten when MacPorts was updated and it had the skip-networking option enabled.

skip-networking

So the problem was solved by just commenting it out and restarting MySQL server.