0

Can't seem to get my Tomcat to connect to my Docker container.

Logs are spitting out the following at the root of the stack trace:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
    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:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
    at com.mysql.jdbc.Util.getInstance(Util.java:408)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:919)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:898)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:887)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:861)
    at com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2095)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2020)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:768)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
    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:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:385)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:323)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:117)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:123)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:367)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:196)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541)
    ... 176 more
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.GeneratedConstructorAccessor66.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:990)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:335)
    at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2187)
    at com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2036)
    ... 192 more
Caused by: java.net.UnknownHostException: mysql
    at java.net.InetAddress.getAllByName0(InetAddress.java:1280)
    at java.net.InetAddress.getAllByName(InetAddress.java:1192)
    at java.net.InetAddress.getAllByName(InetAddress.java:1126)
    at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:188)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:299)
    ... 194 more

Setup:

  • Windows 10
  • JDK/JRE 1.8
  • Tomcat 7
  • Docker 19
  • MySQL 5.7

Configuration:

database.jdbcUrl=jdbc:mysql://internal-mysql:3307/app_main?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&sendFractionalSeconds=false&useSSL=false&rewriteBatchedStatements=true

docker-compose.yml:

  mysql:
    restart: always
    image: "percona:5.7"
    ports:
      - "3307:3307"
    environment:
      MYSQL_USER: root
      MYSQL_PASSWORD: password
    volumes:
      - ./mysql/conf:/etc/mysql:ro
      - ./mysql/initdb.d:/docker-entrypoint-initdb.d:rw
    healthcheck:
      test: ["CMD-SHELL", "mysqlshow --host=127.0.0.1 --port 3307 --user=root--password=password app_main"]
      interval: 15s
      timeout: 1s
      retries: 5
      start_period: 30s
    networks:
      default:
        aliases:
          - internal-mysql

Miscellaneous:

  • Tried setting the my.cnf setting bind-address = 0.0.0.0 and skip-networking is not set.
  • Windows Firewalls are off.

Edit: I am able to connect to the Docker/MySQL container perfectly fine through a standalone program like HeidiSQL or Workbench via internal-mysql:3307. So it seems the connection issues lie solely on the Java and/or Tomcat side and not the container.

CRZZ
  • 1
  • 1
  • 1
    What have you tried so far to debug the problem? Are you sure that the server is running on port `3307` - usually, port `3306` is used – Nico Haase Apr 28 '20 at 21:05
  • Probe that port to make sure it's listening. In linux you would typically do: `telnet internal-mysql 3307`. – The Impaler Apr 28 '20 at 21:07
  • @NicoHaase, I tried all the proposed solutions in this question: https://stackoverflow.com/questions/6865538/solving-a-communications-link-failure-with-jdbc-and-mysql – CRZZ Apr 28 '20 at 21:28
  • @TheImpaler, it's definitely listening and I can log in via the command line or third-party tools just fine; I added an edit to my original question. – CRZZ Apr 28 '20 at 21:30
  • Where is the Tomcat application running? If it's in Docker, can you also include the relevant `docker-compose.yml` fragment? Have you specifically reconfigured the database to listen on the non-default port 3307? – David Maze Apr 28 '20 at 22:04
  • @DavidMaze, Tomcat is just a local instance and not via Docker. The only place I've configured MySQL is on the docker-compose.yml file I posted in the original question. – CRZZ Apr 28 '20 at 23:02
  • Oh, and the "my.cnf" file has the correct port, too: 3307. – CRZZ Apr 28 '20 at 23:40
  • If Tomcat is running outside of Docker, it can't use the Docker-internal hostnames. Use the DNS name or IP address of the host system and the published port (the first number from `ports:`); you can use `localhost` if they're on the same physical system and you're not running Docker Toolbox or a similar VM-oriented setup. – David Maze Apr 29 '20 at 00:02
  • @DavidMaze, I do have it all running on the same physical system (ie. my laptop). "internal-mysql" is also mapped to "127.0.0.1" in my hosts file to avoid any IPV6 concerns I hope. I don't have Toolbox installed; apparently it's obsolete with the newer Docker for Windows platform. But yea.. I totally get that it has to be something seemingly simple that's getting in the way but I feel like I've exhausted every avenue and Google'd almost every corner of the internet. – CRZZ Apr 29 '20 at 04:21
  • According to the error message, you have configured your application to use a jdbc URL starting with `jdbc:mysql://mysql`, not one with `jdbc:mysql://internal-mysql`. And if tomcat is running outside docker on your local machine, you should use `localhost:3307` as the host name and port. – Mark Rotteveel Apr 29 '20 at 12:05

0 Answers0