Cannot connect to remote database from docker with java application

Why my java application cannot connect to my mysql server ?

docker-compose.yml

version: "3"

services:
  chiesulu:
    #image: 523840521829.dkr.ecr.us-east-1.amazonaws.com/djammadev/chiesulu:latest
    image: djammadev/chiesulu:latest
    ports:
      - 9030:80
    env_file:
      - setenv.env
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
      restart_policy:
        condition: on-failure

volumes:
  db-data:

setenv.env

EBEAN_DATASOURCE=db
DATABASE_USERNAME=mysql-user
DATABASE_PASSWORD=mysql-user-password
DATABASE_URL=jdbc:mysql://mysql-server.com/mydb?serverTimezone=UTC
DATABASE_DRIVER=com.mysql.cj.jdbc.Driver

Error

chiesulu_1  | io.ebean.datasource.DataSourceInitialiseException: Error initialising DataSource with user: root url:jdbc:mysql://mysql-server.com/mydb?serverTimezone=UTC error:Could not create connection to database server. Attempted reconnect 10 times. Giving up.
chiesulu_1  |   at io.ebean.datasource.pool.ConnectionPool.<init>(ConnectionPool.java:250)
chiesulu_1  |   at io.ebean.datasource.pool.ConnectionPoolFactory.createPool(ConnectionPoolFactory.java:14)
chiesulu_1  |   at io.ebean.datasource.DataSourceFactory.create(DataSourceFactory.java:26)
chiesulu_1  |   at io.ebeaninternal.server.core.InitDataSource.create(InitDataSource.java:121)
chiesulu_1  |   at io.ebeaninternal.server.core.InitDataSource.createFromConfig(InitDataSource.java:116)
chiesulu_1  |   at io.ebeaninternal.server.core.InitDataSource.initDataSource(InitDataSource.java:49)
chiesulu_1  |   at io.ebeaninternal.server.core.InitDataSource.initialise(InitDataSource.java:34)
chiesulu_1  |   at io.ebeaninternal.server.core.InitDataSource.init(InitDataSource.java:25)
chiesulu_1  |   at io.ebeaninternal.server.core.DefaultContainer.setDataSource(DefaultContainer.java:229)
chiesulu_1  |   at io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:90)
chiesulu_1  |   at io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:63)
chiesulu_1  |   at io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:35)
chiesulu_1  |   at io.ebean.DatabaseFactory.create(DatabaseFactory.java:63)
chiesulu_1  |   at io.ebean.DbContext.getWithCreate(DbContext.java:105)
chiesulu_1  |   at io.ebean.DbContext.<init>(DbContext.java:44)
chiesulu_1  |   at io.ebean.DbContext.<clinit>(DbContext.java:24)
chiesulu_1  |   at io.ebean.DB.<clinit>(DB.java:65)
chiesulu_1  |   at io.ebean.Finder.db(Finder.java:123)
chiesulu_1  |   at io.ebean.Finder.byId(Finder.java:154)
chiesulu_1  |   at com.djammadev.chiesulu.resources.OwnershipResource.getConnected(OwnershipResource.java:41)
chiesulu_1  |   at com.djammadev.chiesulu.resources.OwnershipResource.getBaseKey(OwnershipResource.java:112)
chiesulu_1  |   at com.djammadev.chiesulu.resources.BandResource.getBaseKey(BandResource.java:51)
chiesulu_1  |   at com.shinitech.djammadev.resources.BasicResource.buildKey(BasicResource.java:343)
chiesulu_1  |   at com.shinitech.djammadev.resources.AbstractEntityResource.getAll(AbstractEntityResource.java:55)
chiesulu_1  |   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
chiesulu_1  |   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
chiesulu_1  |   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
chiesulu_1  |   at java.lang.reflect.Method.invoke(Method.java:498)
chiesulu_1  |   at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:76)
chiesulu_1  |   at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:148)
chiesulu_1  |   at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:191)
chiesulu_1  |   at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:243)
chiesulu_1  |   at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
chiesulu_1  |   at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
chiesulu_1  |   at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
chiesulu_1  |   at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
chiesulu_1  |   at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:277)
chiesulu_1  |   at org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
chiesulu_1  |   at org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
chiesulu_1  |   at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
chiesulu_1  |   at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
chiesulu_1  |   at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
chiesulu_1  |   at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
chiesulu_1  |   at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
chiesulu_1  |   at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
chiesulu_1  |   at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
chiesulu_1  |   at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
chiesulu_1  |   at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
chiesulu_1  |   at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
chiesulu_1  |   at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
chiesulu_1  |   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
chiesulu_1  |   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
chiesulu_1  |   at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
chiesulu_1  |   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
chiesulu_1  |   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
chiesulu_1  |   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
chiesulu_1  |   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
chiesulu_1  |   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
chiesulu_1  |   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
chiesulu_1  |   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
chiesulu_1  |   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
chiesulu_1  |   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
chiesulu_1  |   at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
chiesulu_1  |   at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
chiesulu_1  |   at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
chiesulu_1  |   at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
chiesulu_1  |   at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
chiesulu_1  |   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
chiesulu_1  |   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
chiesulu_1  |   at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
chiesulu_1  |   at java.lang.Thread.run(Thread.java:748)
chiesulu_1  | Caused by: java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 10 times. Giving up.
chiesulu_1  |   at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110)
chiesulu_1  |   at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
chiesulu_1  |   at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
chiesulu_1  |   at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
chiesulu_1  |   at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
chiesulu_1  |   at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:897)
chiesulu_1  |   at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:822)
chiesulu_1  |   at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:447)
chiesulu_1  |   at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:237)
chiesulu_1  |   at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199)
chiesulu_1  |   at java.sql.DriverManager.getConnection(DriverManager.java:664)
chiesulu_1  |   at java.sql.DriverManager.getConnection(DriverManager.java:208)
chiesulu_1  |   at io.ebean.datasource.pool.ConnectionPool.createUnpooledConnection(ConnectionPool.java:543)
chiesulu_1  |   at io.ebean.datasource.pool.ConnectionPool.createUnpooledConnection(ConnectionPool.java:538)
chiesulu_1  |   at io.ebean.datasource.pool.ConnectionPool.createConnectionForQueue(ConnectionPool.java:757)
chiesulu_1  |   at io.ebean.datasource.pool.PooledConnectionQueue.ensureMinimumConnections(PooledConnectionQueue.java:176)
chiesulu_1  |   at io.ebean.datasource.pool.ConnectionPool.initialise(ConnectionPool.java:298)
chiesulu_1  |   at io.ebean.datasource.pool.ConnectionPool.<init>(ConnectionPool.java:247)
chiesulu_1  |   ... 70 common frames omitted
chiesulu_1  | Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
chiesulu_1  | 
chiesulu_1  | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
chiesulu_1  |   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
chiesulu_1  |   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
chiesulu_1  |   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
chiesulu_1  |   at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
chiesulu_1  |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
chiesulu_1  |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
chiesulu_1  |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
chiesulu_1  |   at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
chiesulu_1  |   at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:340)
chiesulu_1  |   at com.mysql.cj.protocol.a.NativeAuthenticationProvider.negotiateSSLConnection(NativeAuthenticationProvider.java:777)
chiesulu_1  |   at com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:486)
chiesulu_1  |   at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:202)
chiesulu_1  |   at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1348)
chiesulu_1  |   at com.mysql.cj.NativeSession.connect(NativeSession.java:163)
chiesulu_1  |   at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:841)
chiesulu_1  |   ... 82 common frames omitted
chiesulu_1  | Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
chiesulu_1  |   at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
chiesulu_1  |   at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:103)
chiesulu_1  |   at sun.security.ssl.TransportContext.kickstart(TransportContext.java:220)
chiesulu_1  |   at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:428)
chiesulu_1  |   at com.mysql.cj.protocol.ExportControlled.performTlsHandshake(ExportControlled.java:316)
chiesulu_1  |   at com.mysql.cj.protocol.StandardSocketFactory.performTlsHandshake(StandardSocketFactory.java:188)
chiesulu_1  |   at com.mysql.cj.protocol.a.NativeSocketConnection.performTlsHandshake(NativeSocketConnection.java:99)
chiesulu_1  |   at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:331)
chiesulu_1  |   ... 88 common frames omitted
chiesulu_1  | Oct 25, 2021 12:23:07 PM org.apache.catalina.core.StandardWrapperValve invoke
chiesulu_1  | SEVERE: Servlet.service() for servlet [ChiesuluApplication] in context with path [] threw exception [org.glassfish.jersey.server.ContainerException: java.lang.ExceptionInInitializerError] with root cause


Solution 1:

I resolved the issue by adding enabledTLSProtocols query parameter to the link of the mysql server.

As : DATABASE_URL=jdbc:mysql://mysql-server.com/mydatabase?serverTimezone=UTC&enabledTLSProtocols=TLSv1.2

The error was caused by an Exception : javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

This post helps me : https://stackoverflow.com/questions/67332909/why-can-java-not-connect-to-mysql-5-7-after-the-latest-jdk-update-and-how-should