When your MySQL server accepts local connections but rejects JDBC connections (whether from Tomcat or external clients), you're typically facing one of these fundamental issues:
jdbc:mysql://host:port/db
// Common error pattern:
// CommunicationsException: The last packet sent successfully to the server was 0ms ago
First, eliminate basic network issues:
# From client machine:
telnet mysql_server 3306
nc -zv mysql_server 3306
# On MySQL server:
netstat -tuln | grep 3306
Check these critical settings in /etc/mysql/my.cnf
or /etc/my.cnf
:
[mysqld]
bind-address = 0.0.0.0 # Instead of 127.0.0.1
skip-name-resolve # Prevent DNS lookup delays
wait_timeout = 28800 # Default might be too low
interactive_timeout = 28800
max_allowed_packet = 64M
For CentOS/RHEL:
sudo firewall-cmd --permanent --add-port=3306/tcp
sudo firewall-cmd --reload
For Ubuntu/Debian:
sudo ufw allow 3306
The most common pitfall - your user needs remote access rights:
CREATE USER 'appuser'@'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON mydb.* TO 'appuser'@'%';
FLUSH PRIVILEGES;
Enhance your connection URL with these parameters:
jdbc:mysql://host:3306/db?autoReconnect=true&useSSL=false&
serverTimezone=UTC&useLegacyDatetimeCode=false&
connectTimeout=5000&socketTimeout=30000
For context.xml (Tomcat 9+):
<Resource name="jdbc/MySQLDB" auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://host:3306/db?useSSL=false"
username="user" password="pass"
maxTotal="20" maxIdle="10"
validationQuery="SELECT 1" />
When using HikariCP in Spring Boot:
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
If enforcing SSL (recommended for production):
jdbc:mysql://host:3306/db?useSSL=true&
requireSSL=true&verifyServerCertificate=false&
clientCertificateKeyStoreUrl=file:/path/to/keystore&
clientCertificateKeyStorePassword=password&
trustCertificateKeyStoreUrl=file:/path/to/truststore&
trustCertificateKeyStorePassword=password
application.properties configuration:
spring.datasource.url=jdbc:mysql://host:3306/db?useSSL=false&serverTimezone=UTC
spring.datasource.username=user
spring.datasource.password=pass
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
When working with MySQL 5.5 and Java applications, the "Communications link failure" error typically indicates one of these fundamental issues:
// Typical error pattern you might see
try {
Connection conn = DriverManager.getConnection(
"jdbc:mysql://myserver.com:3306/mydb",
"username",
"password");
} catch (SQLException e) {
// This catches our problematic error
System.out.println("Connection failed: " + e.getMessage());
}
Before diving into configuration, let's verify basic connectivity:
# From your application server terminal:
telnet myserver.com 3306
# Should return "Connected to myserver.com"
# Check MySQL user privileges:
mysql> SELECT Host, User FROM mysql.user;
mysql> SHOW GRANTS FOR 'youruser'@'%';
MySQL 5.5 has several security defaults that often block remote connections:
# In my.cnf or my.ini:
[mysqld]
bind-address = 0.0.0.0 # Instead of 127.0.0.1
skip-name-resolve # Helps with connection speed
max_allowed_packet=64M # Prevents packet size issues
# Critical for JDBC:
wait_timeout = 28800
interactive_timeout = 28800
The basic connection string often needs additional parameters:
String url = "jdbc:mysql://myserver.com:3306/mydb" +
"?useSSL=false" + // For local/dev environments
"&autoReconnect=true" + // Helps with dropped connections
"&failOverReadOnly=false" + // Important for write operations
"&maxReconnects=10" + // Reconnection attempts
"&connectTimeout=5000" + // 5 second timeout
"&socketTimeout=30000"; // 30 second socket timeout
For Tomcat's context.xml or server.xml:
<Resource name="jdbc/MyDB"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://myserver.com:3306/mydb?useSSL=false"
username="dbuser"
password="dbpass"
maxActive="100"
maxIdle="30"
maxWait="10000"
validationQuery="SELECT 1"
testOnBorrow="true"/>
MySQL 5.5 works best with specific JDBC driver versions:
// Maven dependency for MySQL Connector/J
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version> // Stable for MySQL 5.5
</dependency>
Linux administrators often overlook these:
# Check firewall rules:
sudo iptables -L -n | grep 3306
# For CentOS/RHEL:
sudo semanage port -a -t mysqld_port_t -p tcp 3306
sudo setsebool -P httpd_can_network_connect_db 1
When standard approaches fail, enable MySQL's connection logging:
# Temporary logging (remove after debugging!)
mysql> SET GLOBAL general_log = 'ON';
mysql> SET GLOBAL log_output = 'TABLE';
mysql> SELECT * FROM mysql.general_log ORDER BY event_time DESC LIMIT 20;