I try to learn how connect Spring App with MySQL using docker-compose.
I've got the following issue:
spring-db | 2020-03-24 13:18:50+01:00 [Note] [Entrypoint]: Temporary server started.
spring-db | 2020-03-24T12:18:50.676560Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock'
spring-db | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
spring-db | Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
spring-db | Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
spring-db | Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
spring-db | 2020-03-24 13:18:54+01:00 [Note] [Entrypoint]: Creating database spring-db
spring-db | 2020-03-24 13:18:54+01:00 [Note] [Entrypoint]: Creating user spring-db
spring-db | 2020-03-24 13:18:54+01:00 [Note] [Entrypoint]: Giving user spring-db access to schema spring-db
spring-db |
spring-db | 2020-03-24 13:18:54+01:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/spring-db.sql
spring-db |
spring-db |
spring-db | 2020-03-24 13:18:55+01:00 [Note] [Entrypoint]: Stopping temporary server
spring-db | 2020-03-24T12:18:55.410358Z 15 [System] [MY-013172] [Server] Received SHUTDOWN from user root. Shutting down mysqld (Version: 8.0.19).
spring-db | 2020-03-24T12:18:57.128567Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL.
spring-db | 2020-03-24 13:18:57+01:00 [Note] [Entrypoint]: Temporary server stopped
spring-db |
spring-db | 2020-03-24 13:18:57+01:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
Therefore I received following error:
spring-app | 2020-03-24 12:19:11.993 ERROR 1 --- [nio-8080-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection] with root cause
spring-app |
spring-app | java.net.ConnectException: Connection refused (Connection refused)
Has anyone met a similar problem?
Thank you in advance for your help.
I found I made many mistakes.
Firstly configuration
Configuration
#ComponentScan("SpringAndDocker")
#EnableJpaRepositories("SpringAndDocker.repository")
public class ApplicationConfig {
#Value("${db.driver}")
private String databaseDriver;
#Value("${db.password}")
private String databasePassword;
#Value("${db.url}")
private String databaseUrl;
#Value("${db.username}")
private String databaseUsername;
#Value("${hibernate.dialect}")
private String hibernateDialect;
#Value("${hibernate.show_sql}")
private String hibernateShowSql;
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
#Resource
private Environment env;
#Bean
public DataSource dataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(databaseDriver);
dataSource.setUrl(databaseUrl);
dataSource.setUsername(databaseUsername);
dataSource.setPassword(databasePassword);
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory()
{
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
entityManagerFactoryBean.setJpaProperties(hibProperties());
return entityManagerFactoryBean;
}
private Properties hibProperties()
{
Properties properties = new Properties();
properties.put("hibernate.dialect", hibernateDialect);
properties.put("hibernate.show_sql", hibernateShowSql);
return properties;
}
#Bean
public JpaTransactionManager transactionManager()
{
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
Secondly docker-compose.yaml
db:
image: library/postgres:alpine
restart: always
hostname: spring-db
container_name: spring-db
volumes:
- /etc/localtime:/etc/localtime:ro
- ./docker/db/spring-db.sql:/docker-entrypoint-initdb.d/spring-db.sql:ro
- ./docker/db/spring-db.sql:/opt/db/spring-db.sql
environment:
- MYSQL_ROOT_PASSWORD=none
- MYSQL_DATABASE=spring-db
networks:
- spring
The hostname above is spring-db. But according to application.properties
# Database related properties
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:5432/spring-db
db.username=mysql
db.password=none
# Hibernate related properties
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.show_sql=false
entitymanager.packages.to.scan=pl.insudi.model
spring.main.allow-bean-definition-overriding=true
I tried to connect to localhost instead of spring-db.
That was the reason - I should have used the same hostname as in docker-compose.
Also to connect Hibernate properly I needed to use
db.url=jdbc:mysql://insudi-db:3306/insudi-db?allowPublicKeyRetrieval=true&useSSL=false
Related
I want to use docker compose to connect a node program, in one container, to a MySQL database, in another container. The database seems to start fine, but my index.js file throws an error: Cannot find module 'mysql2/promise'
I've tried installing different packages with npm, and even edited various lines in my package.json file in desperation, but to no avail; always the same error. Here are the relevant files, and the output of the commands that work so far.
$ npm install mysql2
npm WARN simplyanything#1.0.0 No repository field.
npm WARN simplyanything#1.0.0 No license field.
+ mysql2#2.3.3
updated 1 package and audited 101 packages in 3.302s
found 0 vulnerabilities
$ sudo npm install mysql2-promise
+ mysql2-promise#0.1.4
updated 1 package and audited 101 packages in 3.772s
found 0 vulnerabilities
package.json
{
"name": "simplyanything",
"version": "1.0.0",
"scripts": {
"start": "node index.js"
},
"description": "Actions party game",
"dependencies": {
"express": "^4.17.1",
"mysql2": "^2.3.3",
"mysql2-promise": "^0.1.4",
"socket.io": "^4.4.1"
},
"author": "Chris DeHaan"
}
index.js
const express = require('express');
let app = express();
let http = require('http').createServer(app);
const io = require('socket.io')(http, {pingTimeout: 60000});
app.use(express.static('public'));
app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); });
http.listen(3000, () => { console.log('listening on *:3000'); });
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
connectionLimit : 100,
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
[.... and so on]
Dockerfile
FROM node:latest
WORKDIR /sa/
COPY package.json .
RUN npm install
COPY . .
docker-compose.yml
version: '3.8'
services:
web:
build:
context: .
env_file: ./.env
command: npm start
volumes:
- .:/sa/
- /sa/node_modules
ports:
- $NODE_LOCAL_PORT:$NODE_DOCKER_PORT
depends_on:
- mysqldb
environment:
MYSQL_HOST: mysqldb
mysqldb:
image: mysql
env_file: ./.env
environment:
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
MYSQL_DATABASE: $MYSQL_DATABASE
ports:
- $MYSQL_LOCAL_PORT:$MYSQL_DOCKER_PORT
volumes:
- mysql:/var/lib/mysql
- mysql_config:/etc/mysql
volumes:
mysql:
mysql_config:
.env
MYSQL_USER=simplyanythingUser
MYSQL_ROOT_PASSWORD=[Well, you don't need to know this]
MYSQL_DATABASE=simplyanything
MYSQL_LOCAL_PORT=3306
MYSQL_DOCKER_PORT=3306
NODE_LOCAL_PORT=3000
NODE_DOCKER_PORT=3000
$ sudo docker build -t sa .
Sending build context to Docker daemon 9.526MB
Step 1/5 : FROM node:latest
---> e6bed6a65a54
Step 2/5 : WORKDIR /sa/
---> Using cache
---> 3da61e5a5928
Step 3/5 : COPY package.json .
---> Using cache
---> 1e7bbeaaa894
Step 4/5 : RUN npm install
---> Using cache
---> 52f36e54d698
Step 5/5 : COPY . .
---> e0a50567567b
Successfully built e0a50567567b
Successfully tagged sa:latest
$ node index.js
Debugger listening on ws://127.0.0.1:44273/a1b49bfc-83e7-47dd-ba53-64a8df19ccc9
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
listening on *:3000
(and it works in the browser at this point)
$ sudo docker-compose up
Starting sa_mysqldb_1 ... done
Starting sa_web_1 ... done
Attaching to sa_mysqldb_1, sa_web_1
mysqldb_1 | 2022-02-08 08:31:21+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
mysqldb_1 | 2022-02-08 08:31:21+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
mysqldb_1 | 2022-02-08 08:31:21+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
mysqldb_1 | 2022-02-08T08:31:21.660916Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.28) starting as process 1
mysqldb_1 | 2022-02-08T08:31:21.747461Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
web_1 |
web_1 | > simplyanything#1.0.0 start
web_1 | > node index.js
web_1 |
mysqldb_1 | 2022-02-08T08:31:23.587278Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
web_1 | node:internal/modules/cjs/loader:936
web_1 | throw err;
web_1 | ^
web_1 |
web_1 | Error: Cannot find module 'mysql2/promise'
web_1 | Require stack:
web_1 | - /sa/index.js
web_1 | at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
web_1 | at Function.Module._load (node:internal/modules/cjs/loader:778:27)
web_1 | at Module.require (node:internal/modules/cjs/loader:999:19)
web_1 | at require (node:internal/modules/cjs/helpers:102:18)
web_1 | at Object.<anonymous> (/sa/index.js:13:15)
web_1 | at Module._compile (node:internal/modules/cjs/loader:1097:14)
web_1 | at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
web_1 | at Module.load (node:internal/modules/cjs/loader:975:32)
web_1 | at Function.Module._load (node:internal/modules/cjs/loader:822:12)
web_1 | at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) {
web_1 | code: 'MODULE_NOT_FOUND',
web_1 | requireStack: [ '/sa/index.js' ]
web_1 | }
web_1 |
web_1 | Node.js v17.4.0
mysqldb_1 | 2022-02-08T08:31:25.086275Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
mysqldb_1 | 2022-02-08T08:31:25.086445Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
mysqldb_1 | 2022-02-08T08:31:25.277625Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
mysqldb_1 | 2022-02-08T08:31:25.354311Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
mysqldb_1 | 2022-02-08T08:31:25.355558Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.28' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
I'm really stuck because everything it needs seems to be installed, and it works when I run it on the command line with node index.js so obviously there's something I'm missing in setting up my container, or getting compose to connect them. Any advice would be much appreciated. Cheers.
Good afternoon, I had the same problem. You could try to use
npm install mysql2
When I execute the docker-compose up command, the following error is generated:
Caused by: java.net.ConnectException: Connection refused
I am trying to establish a connection between two containers, MySQL and My-API container, using docker-compose, but it is somehow not connecting. Here is the docker-compose.yml:
version: '3'
services:
discovery-mysql:
image: mysql:5.7.34
container_name: discovery-mysql
environment:
- MYSQL_ROOT_PASSWORD=tomo
- MYSQL_DATABASE=r2dbc
ports:
- 3307:3306
networks:
- common-network
flyway:
image: flyway/flyway
command:
- url=jdbc:mysql://discovery-mysql:3306/r2dbc?useUnicode=true&characterEncoding=utf8&useSSL=false -user=root -password=tomo migrate
volumes:
- ./src/main/resources/db/migration:/flyway/sql
- ./flyway/conf/flyway.config:/flyway.config
depends_on:
- discovery-mysql
networks:
- common-network
discovery-app:
image: tomojava3284/helloworldapi:latest
restart: on-failure
depends_on:
- discovery-mysql
ports:
- 8001:8080
environment:
- spring.datasource.url=r2dbc:mysql://root:tomo#discovery-mysql:3306/r2dbc
networks:
- common-network
networks:
common-network:
driver: bridge
Things that I had tried:
I added networks: -common-network to put into the same network, but didn't work. I don't see anything wrong with the URL r2dbc:mysql://root:tomo#discovery-mysql:3306/r2dbc.
By the way, when I run the program locally on IDE (not using docker-compose up), given the url=r2dbc:mysql://root:tomo#127.0.0.1:3306/r2dbc, it works fine.
I have seen similar threads on stack overflow, but many of their solutions didn't work (I specified in the "Things that I had tried" section).
What could be the reason that the lead to the error Caused by: java.net.ConnectException: Connection refused?
Here are the full details of errors:
C:\Users\me\github\HelloWorld>docker-compose up
WARNING: Found orphan containers (mysql) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Starting discovery-mysql ... done
Starting helloworld_flyway_1 ... done
Starting helloworld_discovery-app_1 ... done
Attaching to discovery-mysql, helloworld_flyway_1, helloworld_discovery-app_1
discovery-mysql | 2021-06-23 16:03:23+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.34-1debian10 started.
discovery-mysql | 2021-06-23 16:03:23+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
discovery-mysql | 2021-06-23 16:03:23+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.34-1debian10 started.
discovery-mysql | 2021-06-23T16:03:23.899462Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
discovery-mysql | 2021-06-23T16:03:23.900841Z 0 [Note] mysqld (mysqld 5.7.34) starting as process 1 ...
discovery-mysql | 2021-06-23T16:03:23.903779Z 0 [Note] InnoDB: PUNCH HOLE support available
discovery-mysql | 2021-06-23T16:03:23.903816Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
discovery-mysql | 2021-06-23T16:03:23.903821Z 0 [Note] InnoDB: Uses event mutexes
discovery-mysql | 2021-06-23T16:03:23.903824Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
discovery-mysql | 2021-06-23T16:03:23.903827Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
discovery-mysql | 2021-06-23T16:03:23.903829Z 0 [Note] InnoDB: Using Linux native AIO
discovery-mysql | 2021-06-23T16:03:23.904263Z 0 [Note] InnoDB: Number of pools: 1
discovery-mysql | 2021-06-23T16:03:23.904371Z 0 [Note] InnoDB: Using CPU crc32 instructions
discovery-mysql | 2021-06-23T16:03:23.905996Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
discovery-mysql | 2021-06-23T16:03:23.914593Z 0 [Note] InnoDB: Completed initialization of buffer pool
discovery-mysql | 2021-06-23T16:03:23.916694Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
discovery-mysql | 2021-06-23T16:03:23.928540Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
discovery-mysql | 2021-06-23T16:03:23.947396Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
discovery-mysql | 2021-06-23T16:03:23.947471Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
discovery-mysql | 2021-06-23T16:03:23.978325Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
discovery-mysql | 2021-06-23T16:03:23.978805Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
discovery-mysql | 2021-06-23T16:03:23.978846Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
discovery-mysql | 2021-06-23T16:03:23.979683Z 0 [Note] InnoDB: 5.7.34 started; log sequence number 12664810
discovery-mysql | 2021-06-23T16:03:23.979948Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
discovery-mysql | 2021-06-23T16:03:23.980060Z 0 [Note] Plugin 'FEDERATED' is disabled.
discovery-mysql | 2021-06-23T16:03:23.982100Z 0 [Note] InnoDB: Buffer pool(s) load completed at 210623 16:03:23
discovery-mysql | 2021-06-23T16:03:23.984495Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
discovery-mysql | 2021-06-23T16:03:23.984525Z 0 [Note] Skipping generation of SSL certificates as certificate files are present in data directory.
discovery-mysql | 2021-06-23T16:03:23.985024Z 0 [Warning] CA certificate ca.pem is self signed.
discovery-mysql | 2021-06-23T16:03:23.985071Z 0 [Note] Skipping generation of RSA key pair as key files are present in data directory.
discovery-mysql | 2021-06-23T16:03:23.985582Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
discovery-mysql | 2021-06-23T16:03:23.985650Z 0 [Note] IPv6 is available.
discovery-mysql | 2021-06-23T16:03:23.985661Z 0 [Note] - '::' resolves to '::';
discovery-mysql | 2021-06-23T16:03:23.985676Z 0 [Note] Server socket created on IP: '::'.
discovery-mysql | 2021-06-23T16:03:23.992611Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
discovery-mysql | 2021-06-23T16:03:23.999904Z 0 [Note] Event Scheduler: Loaded 0 events
discovery-mysql | 2021-06-23T16:03:24.000165Z 0 [Note] mysqld: ready for connections.
discovery-mysql | Version: '5.7.34' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
flyway_1 | ERROR: Invalid argument: url=jdbc:mysql://discovery-mysql:3306/r2dbc?useUnicode=true&characterEncoding=utf8&useSSL=false -user=root -password=tomo migrate
helloworld_flyway_1 exited with code 1
discovery-app_1 |
discovery-app_1 | . ____ _ __ _ _
discovery-app_1 | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
discovery-app_1 | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
discovery-app_1 | \\/ ___)| |_)| | | | | || (_| | ) ) ) )
discovery-app_1 | ' |____| .__|_| |_|_| |_\__, | / / / /
discovery-app_1 | =========|_|==============|___/=/_/_/_/
discovery-app_1 | :: Spring Boot :: (v2.5.0)
discovery-app_1 |
discovery-app_1 | 2021-06-23 16:03:25.501 INFO 1 --- [ main] c.t.HelloWorld.HelloWorldApplication : Starting HelloWorldApplication v0.0.1-SNAPSHOT using Java 16.0.1 on 1d485fdb3de3 with PID 1
(/app.jar started by root in /)
discovery-app_1 | 2021-06-23 16:03:25.503 INFO 1 --- [ main] c.t.HelloWorld.HelloWorldApplication : No active profile set, falling back to default profiles: default
discovery-app_1 | 2021-06-23 16:03:26.119 INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data R2DBC repositories in DEFAULT mode.
discovery-app_1 | 2021-06-23 16:03:26.242 INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 118 ms. Found 1 R2DBC repository interfaces.
discovery-app_1 | ****************************************************************************************************************
discovery-app_1 | r2dbc:mysql://root:tomo#discovery-mysql:3306/r2dbc // System.out.println(#Value("${spring.datasource.url}"))
discovery-app_1 | ****************************************************************************************************************
discovery-app_1 | 2021-06-23 16:03:27.354 INFO 1 --- [ main] o.f.c.internal.license.VersionPrinter : Flyway Community Edition 7.10.0 by Redgate
discovery-app_1 | 2021-06-23 16:03:27.469 WARN 1 --- [ main] onfigReactiveWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.spring
framework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfi
guration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.internal.exception.FlywaySqlException:
discovery-app_1 | Unable to obtain connection from database: Communications link failure
discovery-app_1 |
discovery-app_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
discovery-app_1 | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------
discovery-app_1 | SQL State : 08S01
discovery-app_1 | Error Code : 0
discovery-app_1 | Message : Communications link failure
discovery-app_1 |
discovery-app_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
discovery-app_1 |
discovery-app_1 | 2021-06-23 16:03:27.485 INFO 1 --- [ main] ConditionEvaluationReportLoggingListener :
discovery-app_1 |
discovery-app_1 | Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
discovery-app_1 | 2021-06-23 16:03:27.505 ERROR 1 --- [ main] o.s.boot.SpringApplication : Application run failed
discovery-app_1 |
discovery-app_1 | org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/Flyw
ayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.internal.exception.FlywaySqlException:
discovery-app_1 | Unable to obtain connection from database: Communications link failure
discovery-app_1 |
discovery-app_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
discovery-app_1 | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------
discovery-app_1 | SQL State : 08S01
discovery-app_1 | Error Code : 0
discovery-app_1 | Message : Communications link failure
discovery-app_1 |
discovery-app_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
discovery-app_1 |
discovery-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602) ~[spring-beans-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:64) ~[spring-boot-2.5.0.jar!/:2.5.0]
discovery-app_1 | at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.5.0.jar!/:2.5.0]
discovery-app_1 | at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:438) ~[spring-boot-2.5.0.jar!/:2.5.0]
discovery-app_1 | at org.springframework.boot.SpringApplication.run(SpringApplication.java:337) ~[spring-boot-2.5.0.jar!/:2.5.0]
discovery-app_1 | at org.springframework.boot.SpringApplication.run(SpringApplication.java:1336) ~[spring-boot-2.5.0.jar!/:2.5.0]
discovery-app_1 | at org.springframework.boot.SpringApplication.run(SpringApplication.java:1325) ~[spring-boot-2.5.0.jar!/:2.5.0]
discovery-app_1 | at com.tomoaki3284.HelloWorld.HelloWorldApplication.main(HelloWorldApplication.java:11) ~[classes!/:0.0.1-SNAPSHOT]
discovery-app_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
discovery-app_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
discovery-app_1 | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
discovery-app_1 | at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
discovery-app_1 | at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[app.jar:0.0.1-SNAPSHOT]
discovery-app_1 | at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[app.jar:0.0.1-SNAPSHOT]
discovery-app_1 | at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[app.jar:0.0.1-SNAPSHOT]
discovery-app_1 | at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) ~[app.jar:0.0.1-SNAPSHOT]
discovery-app_1 | Caused by: org.flywaydb.core.internal.exception.FlywaySqlException:
discovery-app_1 | Unable to obtain connection from database: Communications link failure
discovery-app_1 |
discovery-app_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
discovery-app_1 | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------
discovery-app_1 | SQL State : 08S01
discovery-app_1 | Error Code : 0
discovery-app_1 | Message : Communications link failure
discovery-app_1 |
discovery-app_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
discovery-app_1 |
discovery-app_1 | at org.flywaydb.core.internal.jdbc.JdbcUtils.openConnection(JdbcUtils.java:71) ~[flyway-core-7.10.0.jar!/:na]
discovery-app_1 | at org.flywaydb.core.internal.jdbc.JdbcConnectionFactory.<init>(JdbcConnectionFactory.java:68) ~[flyway-core-7.10.0.jar!/:na]
discovery-app_1 | at org.flywaydb.core.Flyway.execute(Flyway.java:510) ~[flyway-core-7.10.0.jar!/:na]
discovery-app_1 | at org.flywaydb.core.Flyway.migrate(Flyway.java:170) ~[flyway-core-7.10.0.jar!/:na]
discovery-app_1 | at org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer.afterPropertiesSet(FlywayMigrationInitializer.java:66) ~[spring-boot-autoconfigure-2.5.0.jar!/:2.5.0]
discovery-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) ~[spring-beans-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-5.3.7.jar!/:5.3.7]
discovery-app_1 | ... 24 common frames omitted
discovery-app_1 | Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
discovery-app_1 |
discovery-app_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
discovery-app_1 | at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:833) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:453) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at org.springframework.jdbc.datasource.SimpleDriverDataSource.getConnectionFromDriver(SimpleDriverDataSource.java:144) ~[spring-jdbc-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:205) ~[spring-jdbc-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:169) ~[spring-jdbc-5.3.7.jar!/:5.3.7]
discovery-app_1 | at org.flywaydb.core.internal.jdbc.JdbcUtils.openConnection(JdbcUtils.java:55) ~[flyway-core-7.10.0.jar!/:na]
discovery-app_1 | ... 30 common frames omitted
discovery-app_1 | Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
discovery-app_1 |
discovery-app_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
discovery-app_1 | at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
discovery-app_1 | at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78) ~[na:na]
discovery-app_1 | at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
discovery-app_1 | at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[na:na]
discovery-app_1 | at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[na:na]
discovery-app_1 | at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.NativeSession.connect(NativeSession.java:144) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:953) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:823) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | ... 37 common frames omitted
discovery-app_1 | Caused by: java.net.ConnectException: Connection refused
discovery-app_1 | at java.base/sun.nio.ch.Net.connect0(Native Method) ~[na:na]
discovery-app_1 | at java.base/sun.nio.ch.Net.connect(Net.java:576) ~[na:na]
discovery-app_1 | at java.base/sun.nio.ch.Net.connect(Net.java:565) ~[na:na]
discovery-app_1 | at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:588) ~[na:na]
discovery-app_1 | at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:333) ~[na:na]
discovery-app_1 | at java.base/java.net.Socket.connect(Socket.java:645) ~[na:na]
discovery-app_1 | at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:155) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
discovery-app_1 | ... 40 common frames omitted
discovery-app_1 |
// from here, the same log repeatedly because Spring Boot App would restart on failure.
How I am pushing changes every time:
mvnw package && java -jar target/spring-boot-0.0.1-SNAPSHOT.jar
docker build -t tomojava3284/helloworldapi .
docker push tomojava3284/helloworldapi:latest
docker-compose pull
docker-compose up
I think there is a bug there when accessing the database by service name. as a solution I can suggest you use host.docker.internal.
then the URL will be like the below. it will not be a problem in the production mode due to using a managed database.
- spring.datasource.url=r2dbc:mysql://root:tomo#host.docker.internal:3306/r2dbc
https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host
I had a same problem with java and my solution for this issue was setting IP for each service in docker-compose.yml like this :
version: '3'
services:
discovery-mysql:
image: mysql:5.7.34
container_name: discovery-mysql
environment:
- MYSQL_ROOT_PASSWORD=tomo
- MYSQL_DATABASE=r2dbc
ports:
- 3307:3306
networks:
common-network:
ipv4_address: 172.18.0.5
flyway:
image: flyway/flyway
command:
- url=jdbc:mysql://discovery-mysql:3306/r2dbc?useUnicode=true&characterEncoding=utf8&useSSL=false -user=root -password=tomo migrate
volumes:
- ./src/main/resources/db/migration:/flyway/sql
- ./flyway/conf/flyway.config:/flyway.config
depends_on:
- discovery-mysql
networks:
common-network:
ipv4_address: 172.18.0.10
discovery-app:
image: tomojava3284/helloworldapi:latest
restart: on-failure
depends_on:
- discovery-mysql
ports:
- 8001:8080
environment:
- spring.datasource.url=r2dbc:mysql://root:tomo#discovery-mysql:3306/r2dbc
networks:
common-network:
ipv4_address: 172.18.0.15
networks:
common-network:
ipam:
config:
- subnet: 172.18.0.0/16
And your connect url will be
$ r2dbc:mysql://root:tomo# 172.18.0.5:3306/r2dbc
Be careful what IP range you use, maybe this one is no longer free
I am following this tutorial to setup spring boot project with docker-compose. Here is what I did:
My application.properties:
spring.datasource.url = jdbc:mysql://mysql-demo-container:3306/demo_db?useSSL=false
spring.datasource.username = root
spring.datasource.password =root
spring.datasource.tomcat.testWhileIdle = true
spring.datasource.tomcat.timeBetweenEvictionRunsMillis = 60000
spring.datasource.tomcat.validationQuery = SELECT 1
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
My Dockerfile:
`FROM java:8
LABEL maintainer=“foo.bar#gmail.com”
VOLUME /tmp
EXPOSE 8080
ADD target/spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar"]`
I have this docker-compose.yml:
version: '3'
services:
mysql-demo-container:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=demo_db
- MYSQL_PASSWORD=myPass
ports:
- 2012:3306
volumes:
- /data/mysql
spring-boot-jpa-app:
image: spring-boot-jpa-image
build:
context: ./
dockerfile: Dockerfile
depends_on:
- mysql-demo-container
ports:
- 8087:8080
volumes:
- /data/spring-boot-app
I firstly mvn clean install to build the project jar file, then I run docker-compose up to build images & hopefully run containers.
The logs:
$ docker-compose up
Creating network "spring-boot-data-jpa-example-master_default" with the default driver
Creating spring-boot-data-jpa-example-master_mysql-demo-container_1 ... done
Creating spring-boot-data-jpa-example-master_spring-boot-jpa-app_1 ... done
Attaching to spring-boot-data-jpa-example-master_mysql-demo-container_1, spring-boot-data-jpa-example-master_spring-boot-jpa-app_1
mysql-demo-container_1 | Initializing database
mysql-demo-container_1 | 2019-07-02T13:03:05.097872Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
mysql-demo-container_1 | 2019-07-02T13:03:05.098037Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.16) initializing of server in progress as process 29
mysql-demo-container_1 | 2019-07-02T13:03:09.171833Z 5 [Warning] [MY-010453] [Server] root#localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
spring-boot-jpa-app_1 |
spring-boot-jpa-app_1 | . ____ _ __ _ _
spring-boot-jpa-app_1 | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
spring-boot-jpa-app_1 | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
spring-boot-jpa-app_1 | \\/ ___)| |_)| | | | | || (_| | ) ) ) )
spring-boot-jpa-app_1 | ' |____| .__|_| |_|_| |_\__, | / / / /
spring-boot-jpa-app_1 | =========|_|==============|___/=/_/_/_/
spring-boot-jpa-app_1 | :: Spring Boot :: (v1.5.9.RELEASE)
spring-boot-jpa-app_1 |
spring-boot-jpa-app_1 | 2019-07-02 13:03:11.516 INFO 1 --- [ main] .s.e.SpringBootDataJpaExampleApplication : Starting SpringBootDataJpaExampleApplication v0.0.1-SNAPSHOT on 3c0d94b76fd6 with PID 1 (/spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar started by root in /)
spring-boot-jpa-app_1 | 2019-07-02 13:03:11.556 INFO 1 --- [ main] .s.e.SpringBootDataJpaExampleApplication : No active profile set, falling back to default profiles: default
spring-boot-jpa-app_1 | 2019-07-02 13:03:11.979 INFO 1 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#6d5380c2: startup date [Tue Jul 02 13:03:11 UTC 2019]; root of context hierarchy
mysql-demo-container_1 | 2019-07-02T13:03:13.525348Z 0 [System] [MY-013170] [Server] /usr/sbin/mysqld (mysqld 8.0.16) initializing of server has completed
mysql-demo-container_1 | Database initialized
mysql-demo-container_1 | MySQL init process in progress...
mysql-demo-container_1 | MySQL init process in progress...
mysql-demo-container_1 | MySQL init process in progress...
mysql-demo-container_1 | 2019-07-02T13:03:15.636380Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
mysql-demo-container_1 | 2019-07-02T13:03:15.636539Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.16) starting as process 80
mysql-demo-container_1 | 2019-07-02T13:03:18.070695Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
mysql-demo-container_1 | 2019-07-02T13:03:18.081045Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
mysql-demo-container_1 | 2019-07-02T13:03:18.152808Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.16' socket: '/var/run/mysqld/mysqld.sock' port: 0 MySQL Community Server - GPL.
mysql-demo-container_1 | 2019-07-02T13:03:18.311442Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock'
spring-boot-jpa-app_1 | 2019-07-02 13:03:20.039 INFO 1 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
spring-boot-jpa-app_1 | 2019-07-02 13:03:20.221 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
spring-boot-jpa-app_1 | 2019-07-02 13:03:20.232 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.23
spring-boot-jpa-app_1 | 2019-07-02 13:03:21.210 INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
spring-boot-jpa-app_1 | 2019-07-02 13:03:21.213 INFO 1 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 9251 ms
spring-boot-jpa-app_1 | 2019-07-02 13:03:22.153 INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
spring-boot-jpa-app_1 | 2019-07-02 13:03:22.169 INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
spring-boot-jpa-app_1 | 2019-07-02 13:03:22.178 INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
spring-boot-jpa-app_1 | 2019-07-02 13:03:22.178 INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
spring-boot-jpa-app_1 | 2019-07-02 13:03:22.181 INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
mysql-demo-container_1 | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
mysql-demo-container_1 | Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
spring-boot-jpa-app_1 | 2019-07-02 13:03:25.161 ERROR 1 --- [ main] o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.
spring-boot-jpa-app_1 |
spring-boot-jpa-app_1 | com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
spring-boot-jpa-app_1 |
spring-boot-jpa-app_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
spring-boot-jpa-app_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]
spring-boot-jpa-app_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_111]
spring-boot-jpa-app_1 | at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_111]
spring-boot-jpa-app_1 | at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_111]
spring-boot-jpa-app_1 | at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:989) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:341) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2189) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2222) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2017) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:779) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]
spring-boot-jpa-app_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_111]
spring-boot-jpa-app_1 | at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_111]
spring-boot-jpa-app_1 | at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_111]
spring-boot-jpa-app_1 | at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:389) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:330) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
spring-boot-jpa-app_1 | at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:310) ~[tomcat-jdbc-8.5.23.jar!/:na]
spring-boot-jpa-app_1 | at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203) ~[tomcat-jdbc-8.5.23.jar!/:na]
spring-boot-jpa-app_1 | at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:735) [tomcat-jdbc-8.5.23.jar!/:na]
spring-boot-jpa-app_1 | at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:667) [tomcat-jdbc-8.5.23.jar!/:na]
spring-boot-jpa-app_1 | at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:482) [tomcat-jdbc-8.5.23.jar!/:na]
spring-boot-jpa-app_1 | at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154) [tomcat-jdbc-8.5.23.jar!/:na]
spring-boot-jpa-app_1 | at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) [tomcat-jdbc-8.5.23.jar!/:na]
spring-boot-jpa-app_1 | at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) [tomcat-jdbc-8.5.23.jar!/:na]
spring-boot-jpa-app_1 | at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131) [tomcat-jdbc-8.5.23.jar!/:na]
spring-boot-jpa-app_1 | at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) [spring-jdbc-4.3.13.RELEASE.jar!/:4.3.13.RELEASE]
spring-boot-jpa-app_1 | at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) [spring-jdbc-4.3.13.RELEASE.jar!/:4.3.13.RELEASE]
spring-boot-jpa-app_1 | at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:326) [spring-jdbc-4.3.13.RELEASE.jar!/:4.3.13.RELEASE]
spring-boot-jpa-app_1 | at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:366) [spring-jdbc-4.3.13.RELEASE.jar!/:4.3.13.RELEASE]
spring-boot-jpa-app_1 | at org.springframework.boot.autoconfigure.orm.jpa.DatabaseLookup.getDatabase(DatabaseLookup.java:72) [spring-boot-autoconfigure-1.5.9.RELEASE.jar!/:1.5.9.RELEASE]
spring-boot-jpa-app_1 | at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties.determineDatabase(JpaProperties.java:139) [spring-boot-autoconfigure-1.5.9.
As you can see from the beginning of the log, the containers seem created successfully.
Run docker ps shows me:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8fa64acb363d mysql:latest "docker-entrypoint.s…" 30 minutes ago Up 30 minutes 33060/tcp, 0.0.0.0:2012->3306/tcp spring-boot-data-jpa-example-master_mysql-demo-container_1
What could be the reason for the error?
You should be aware of this very important footnote in the reference documentation of Docker Compose:
depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started. If you need to wait for a service to be ready, see Controlling startup order for more on this problem and strategies for solving it.
In your case, your Spring boot container starts right after your MySQL container is being started. There's no guarantee though that MySQL will be able to take connections when Spring boot is setting up its connection pool.
This means that your Spring boot connection will fail to startup, because MySQL isn't ready yet. This results in your application container to be killed.
The solution to this problem is mentioned within the documentation I quoted. Namely, you have to use some kind of polling mechanism to see if you can connect to your database or not.
If you don't want to use tools like wait-for-it or wait-for, you could write a simple Shell script that does something like this:
while ! exec 6<>/dev/tcp/mysql-demo-container/3306; do
echo "Trying to connect to MySQL..."
sleep 10
done
exec java -jar spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar
This also means you have to change the ENTRYPOINT within your Dockerfile to refer to such shell script rather than directly running your JAR file.
OS details
Mint version 19,
Code name : Tara,
PackageBase : Ubuntu Bionic
Cinnamon (64-bit)
I followed this URL to install mysql 5.7 and workbench 6.3
I can check mysql service running
xxxxxxxxx:~$ sudo netstat -nlpt | grep 3306
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1547/mysqld
I also checked bind-address inside file: mysqld.cnf under directory : /etc/mysql/mysql.conf.d/
bind-address = 127.0.0.1
I have written a simple spring application using mysql
Here are all classes written
SpringBootDataJpaExampleApplication
#EnableJpaRepositories(basePackages = "com.springbootdev.examples.repository")
#SpringBootApplication
public class SpringBootDataJpaExampleApplication
{
public static void main(String[] args) {
SpringApplication.run(SpringBootDataJpaExampleApplication.class, args);
}
}
UserController
#RestController
#RequestMapping("/api")
public class UserController {
#Autowired
private UserRepository userRepository;
#GetMapping("/create")
public List<User> users() {
User users = new User();
users.setId(new Long(1));
users.setName("Sam");
users.setCountry("Development");
userRepository.save(users);
return userRepository.findAll();
}
#GetMapping("/users")
public List<User> findAll()
{
return userRepository.findAll();
}
}
UserRepository
public interface UserRepository extends JpaRepository<User, Long>
{
}
User
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String country;
//getters and setters
}
partial pom.xml file. Please see I am using spring boot 1.5.9 and jdk 1.8
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
application.properties
spring.datasource.url = jdbc:mysql://mysql-standalone:3306/test
spring.datasource.username = testuser
spring.datasource.password = testpassword
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto = create
Dockerfile
FROM openjdk:8
VOLUME /tmp
EXPOSE 8080
ADD target/spring-boot-app.jar spring-boot-app.jar
ENTRYPOINT ["java","-jar","spring-boot-app.jar"]
When I run this application locally using IDE it works fine and I can access:
http://localhost:8080/api/users/
and http://localhost:8080/api/create/
I build image out of my application using command
docker build . -t spring-boot-app
I can see image is being built.
xxxxxxxxxx:$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
spring-boot-app latest 069e53a7c389 27 minutes ago 652MB
mysql 5.7 1b30b36ae96a 8 days ago 372MB
Now I run Command to run the mysql container
docker run --name mysql-standalone -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=test -e MYSQL_USER=testuser -e MYSQL_PASSWORD=testpassword -d mysql:5.7
Then I connect to mysql-standalone container from my application(spring-boot-app) (referencing this)
docker run --name spring-boot-app-container --link mysql-standalone:mysql -d spring-boot-app
With this, I can see my application working fine from docker using
http://(docker-container-ip):8080/api/users/ and http://(docker-container-ip):8080/api/create/
Here I wanted to make the same thing work with docker-compose.
Referenced this to install docker compose.
xxxxxxxxxx:~$ docker-compose --version
docker-compose version 1.22.0, build f46880fe
Then I created file docker-compose.yml in my project directory.
version: '3'
services:
mysql-docker-container:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=adminpassword
- MYSQL_DATABASE=test
- MYSQL_USER=testuser
- MYSQL_PASSWORD=testpassword
volumes:
- /data/mysql
spring-boot-app-container:
image: spring-boot-app
build:
context: .
dockerfile: Dockerfile
depends_on:
- mysql-docker-container
ports:
- 8087:8080
volumes:
- /data/spring-boot-app
Changed one line in my application.properties and commented earlier datasource url as below.
spring.datasource.url = jdbc:mysql://mysql-docker-container:3306/test
#spring.datasource.url = jdbc:mysql://mysql-standalone:3306/test
Did clean install so new target jar gets created. I also deleted images and containers from docker.
Then ran below command:
docker-compose up
This is what I see in logs
Creating spring-boot-data-jpa-mysql-docker-no-composer-master_mysql-docker-container_1 ... done
Creating spring-boot-data-jpa-mysql-docker-no-composer-master_spring-boot-app-container_1 ... done
Attaching to spring-boot-data-jpa-mysql-docker-no-composer-master_mysql-docker-container_1, spring-boot-data-jpa-mysql-docker-no-composer-master_spring-boot-app-container_1
spring-boot-app-container_1 |
spring-boot-app-container_1 | . ____ _ __ _ _
spring-boot-app-container_1 | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
spring-boot-app-container_1 | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
spring-boot-app-container_1 | \\/ ___)| |_)| | | | | || (_| | ) ) ) )
spring-boot-app-container_1 | ' |____| .__|_| |_|_| |_\__, | / / / /
spring-boot-app-container_1 | =========|_|==============|___/=/_/_/_/
spring-boot-app-container_1 | :: Spring Boot :: (v1.5.9.RELEASE)
spring-boot-app-container_1 |
spring-boot-app-container_1 | 2018-10-26 01:24:48.748 INFO 1 --- [ main] .s.e.SpringBootDataJpaExampleApplication : Starting SpringBootDataJpaExampleApplication v0.0.1-SNAPSHOT on 582c035536e4 with PID 1 (/spring-boot-app.jar started by root in /)
spring-boot-app-container_1 | 2018-10-26 01:24:48.752 INFO 1 --- [ main] .s.e.SpringBootDataJpaExampleApplication : No active profile set, falling back to default profiles: default
spring-boot-app-container_1 | 2018-10-26 01:24:48.875 INFO 1 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#28c97a5: startup date [Fri Oct 26 01:24:48 UTC 2018]; root of context hierarchy
spring-boot-app-container_1 | 2018-10-26 01:24:51.022 INFO 1 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
spring-boot-app-container_1 | 2018-10-26 01:24:51.063 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
spring-boot-app-container_1 | 2018-10-26 01:24:51.065 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.23
spring-boot-app-container_1 | 2018-10-26 01:24:51.218 INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
spring-boot-app-container_1 | 2018-10-26 01:24:51.218 INFO 1 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2399 ms
spring-boot-app-container_1 | 2018-10-26 01:24:51.335 INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
spring-boot-app-container_1 | 2018-10-26 01:24:51.340 INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
spring-boot-app-container_1 | 2018-10-26 01:24:51.341 INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
spring-boot-app-container_1 | 2018-10-26 01:24:51.341 INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
spring-boot-app-container_1 | 2018-10-26 01:24:51.341 INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
spring-boot-app-container_1 | 2018-10-26 01:24:51.895 ERROR 1 --- [ main] o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.
spring-boot-app-container_1 |
spring-boot-app-container_1 | com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
spring-boot-app-container_1 |
spring-boot-app-container_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
spring-boot-app-container_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_181]
How to fix this error:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
I can see lot of answers on this forum for this similar error message. Tried bunch of those options/answers, but that didn't work.
No answer talks about this combination (linux + spring boot + mysql + docker compose)
Note: This has worked fine without using docker-compose. Have already mentioned the same in above description. Am I making any mistake in docker-compose file or application properties file?
I did see lot of people posting about adding hikari dependency in pom.xml if you are using any spring-boot version < 2.0
<!-- Spring Boot Data 2.0 includes HikariCP by default -->
<!-- <dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.1.0</version>
</dependency> -->
With that I thought of using same application but made changes to my pom.xml as below
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
Then I followed exact same things as mentioned in description of issue. With that I saw bit more clear error as below:
spring-boot-app-container_1 | 2018-10-27 18:51:47.259 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
spring-boot-app-container_1 | 2018-10-27 18:51:48.464 ERROR 1 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during pool initialization.
spring-boot-app-container_1 |
spring-boot-app-container_1 | com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
spring-boot-app-container_1 |
spring-boot-app-container_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
That confirms spring-boot 2.0 uses hikari datasource default.
Now coming back to how I solved the issue.
I changed connection string in application.properties like below:
spring.datasource.url = jdbc:mysql://mysql-docker-container:3306/test?autoReconnect=true&failOverReadOnly=false&maxReconnects=10&useSSL=false
instead of earlier used:
spring.datasource.url = jdbc:mysql://mysql-docker-container:3306/test
The answer was simple. Below change worked for me in Spring-boot 2.0 as well as Spring-boot 1.5.9: (Add this to your connection string)
?autoReconnect=true&failOverReadOnly=false&maxReconnects=10
Some handy commands:
Once containers are up, you can check ip addresses of containers using command:
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
========================================
UPDATE: some additional handy information...
Below is DEPRECATED
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
This needs to be replaced by
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
To fix HikariCP Pool initialization issue/exception, please set HikariCP’s initializationFailTimeout property to 0 (zero), or a negative number.
# HikaryCP Properties
spring.datasource.hikari.initialization-fail-timeout=0
This property controls whether the pool will "fail fast" if the pool cannot be seeded with an initial connection successfully. Any positive number is taken to be the number of milliseconds to attempt to acquire an initial connection; the application thread will be blocked during this period. If a connection cannot be acquired before this timeout occurs, an exception will be thrown. This timeout is applied after the connectionTimeout period. If the value is zero (0), HikariCP will attempt to obtain and validate a connection. If a connection is obtained, but fails validation, an exception will be thrown and the pool not started. However, if a connection cannot be obtained, the pool will start, but later efforts to obtain a connection may fail. A value less than zero will bypass any initial connection attempt, and the pool will start immediately while trying to obtain connections in the background. Consequently, later efforts to obtain a connection may fail. Default: 1
I have been following tutorials on PlayFramework, but it seems that they are all outdated and for older version of Play.
I want to try JUnit test using mysql databse not h2 in-memory database.
I am using ebean ORC (which clearly has different api than it used to have inside play 2.2, and the api is not really well documented).
Anyway I want to try JUnit test on mysql databse, but I am always getting a configuration error.
This is how the JUnit test class looks:
public class ModelsTest extends WithApplication {
public Application app;
#Before
public void setUp() throws FileNotFoundException, IOException {
java.util.Properties externalProps=new java.util.Properties();
externalProps.load(new FileInputStream("resources/test-ebean.properties"));
ServerConfig config = new ServerConfig();
config.setName("test");
config.setDefaultServer(true);
config.loadFromProperties(externalProps);
EbeanServer server = EbeanServerFactory.create(config);
app = Helpers.fakeApplication();
Helpers.start(app);
}
#Test
public void createAndRetrieveUser() {
new User("bob#bob.bob", "admin", "admin").save();
User bob = User.find.where().eq("email", "bob#bob.bob").findUnique();
assertNotNull(bob);
assertEquals("admin", bob.login);
}
#After
public void stopApp() {
Helpers.stop(app);
}
test-ebean.properties file :
ebean.ddl.generate=true
ebean.ddl.run=true
datasource.default=db
datasource.db.username="root"
datasource.db.password="root"
datasource.db.databaseUrl="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8"
datasource.db.databaseDriver=com.mysql.jdbc.Driver
When running test I am getting this error:
[error] Test ModelsTest.createAndRetrieveUser failed:` play.api.Configuration$$anon$1: Configuration error[null], took 4.969 sec
[error] at play.api.Configuration$.configError(Configuration.scala:154)
[error] at play.api.Configuration.reportError(Configuration.scala:806)
[error] at play.Configuration.reportError(Configuration.java:366)
[error] at play.db.ebean.DefaultEbeanConfig$EbeanConfigParser.parse(DefaultEbeanConfig.java:81)
[error] at play.db.ebean.DefaultEbeanConfig$EbeanConfigParser.get(DefaultEbeanConfig.java:60)
[error] at play.db.ebean.DefaultEbeanConfig$EbeanConfigParser.get(DefaultEbeanConfig.java:44)
[error] at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:81)
[error] at com.google.inject.internal.BoundProviderFactory.provision(BoundProviderFactory.java:72)
[error] at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61)
[error] at com.google.inject.internal.BoundProviderFactory.get(BoundProviderFactory.java:62)
[error] at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
[error] at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103)
[error] at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
[error] at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145)
[error] at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
[error] at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
[error] at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
[error] at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:104)
[error] at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85)
[error] at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:267)
[error] at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
[error] at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103)
[error] at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
[error] at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145)
[error] at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
[error] at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:56)
[error] at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
[error] at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103)
[error] at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
[error] at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145)
[error] at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
[error] at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:205)
[error] at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:199)
[error] at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
[error] at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:199)
[error] at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:180)
[error] at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110)
[error] at com.google.inject.Guice.createInjector(Guice.java:96)
[error] at com.google.inject.Guice.createInjector(Guice.java:84)
[error] at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:181)
[error] at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:123)
[error] at play.api.test.FakeApplication.<init>(Fakes.scala:209)
[error] at play.test.FakeApplication.<init>(FakeApplication.java:51)
[error] at play.test.Helpers.fakeApplication(Helpers.java:124)
[error] at play.test.WithApplication.provideFakeApplication(WithApplication.java:46)
[error] at play.test.WithApplication.provideApplication(WithApplication.java:33)
[error] at play.test.WithApplication.startPlay(WithApplication.java:51)
[error] ...
[error] Caused by: java.lang.NullPointerException
[error] at play.db.ebean.DefaultEbeanConfig$EbeanConfigParser.parse(DefaultEbeanConfig.java:79)
[error] ... 78 more
[error] Test ModelsTest.createAndRetrieveUser failed: java.lang.NullPointerException: null, took 4.979 sec
[error] at play.test.Helpers.stop(Helpers.java:376)
[error] at ModelsTest.stopApp(ModelsTest.java:58)
[error] ...
[error] Failed: Total 1, Failed 1, Errors 0, Passed 0
[error] Failed tests:
[error] ModelsTest
[error] (test:testOnly) sbt.TestsFailedException: Tests unsuccessful
I just started learning play (but actually most of tutorials are outdated) and I have spent more time trying to configure it to run than actually coding. I guess I should look up another framework.
You don't need to set up a whole database just for testing (you are free to, of course). Play relies strongly on In-Memory databases (e.g. during development) and you can utilize this also in your tests:
#Test
public void findById() {
running(fakeApplication(inMemoryDatabase("test")), () -> {
User bob = User.findById(21l);
assertEquals("bob#bob.bob", bob.email);
assertEquals("admin", bob.login);
});
}
On the other hand if you really want to test the database access code you can go as far as creating a Database test object:
Database database = Databases.createFrom(
"com.mysql.jdbc.Driver",
"jdbc:mysql://localhost/test"
);
Which again can be in-memory:
Database database = Databases.inMemory(
"mydatabase",
ImmutableMap.of(
"MODE", "MYSQL"
),
ImmutableMap.of(
"logStatements", true
)
);
Just don't forget to release the resources after the test:
#After
public void shutdownDatabase() {
database.shutdown();
}