I'm having trouble getting MySQL 8 (namely mysql:8.0.11 image) to run with Testcontainers. Container startup fails due to timeout, with the following output:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
log4j:WARN No appenders could be found for logger (org.testcontainers.shaded.io.netty.util.internal.logging.InternalLoggerFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
ℹ︎ Checking the system...
✔ Docker version should be at least 1.6.0
✔ Docker environment should have more than 2GB free disk space
✔ File should be mountable
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
org.testcontainers.containers.ContainerLaunchException: Container startup failed
at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:214)
at org.testcontainers.containers.GenericContainer.starting(GenericContainer.java:638)
at org.testcontainers.containers.FailureDetectingExternalResource$1.evaluate(FailureDetectingExternalResource.java:29)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:83)
at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:207)
... 9 more
Caused by: org.testcontainers.containers.ContainerLaunchException: Could not create/start container
at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:279)
at org.testcontainers.containers.GenericContainer.lambda$start$0(GenericContainer.java:209)
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:76)
... 10 more
Caused by: org.rnorth.ducttape.TimeoutException: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:53)
at org.testcontainers.containers.JdbcDatabaseContainer.waitUntilContainerStarted(JdbcDatabaseContainer.java:94)
at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:258)
... 12 more
Caused by: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
at org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:70)
at org.rnorth.ducttape.timeouts.Timeouts.getWithTimeout(Timeouts.java:43)
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:38)
... 14 more
Caused by: java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:205)
at org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:65)
... 16 more
Test ignored.
Process finished with exit code 255
Note:
I've tried overriding MySQLContainer#getDriverClassName to address the JDBC driver warning, but that didn't affect anything.
This can be reproduced with a very simple project using:
plugins {
id 'java'
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.12'
testCompile 'mysql:mysql-connector-java:8.0.11'
testCompile 'org.testcontainers:mysql:1.7.3'
}
public class DemoTests {
@ClassRule
public static MySQLContainer container = new MySQLContainer("mysql:8.0.11");
private DataSource dataSource;
@Before
public void setUp() {
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUrl(container.getJdbcUrl());
dataSource.setUser(container.getUsername());
dataSource.setPassword(container.getPassword());
this.dataSource = dataSource;
}
@Test
public void someTest() throws Exception {
try (Connection con = this.dataSource.getConnection();
PreparedStatement ps = con.prepareStatement("select 1");
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getInt(0));
}
}
}
}
Environment details:
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
$ uname -srvmpio
Linux 4.15.0-22-generic #24-Ubuntu SMP Wed May 16 12:15:17 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
$ java -version
openjdk version "1.8.0_172"
OpenJDK Runtime Environment (Zulu 8.30.0.1-linux64) (build 1.8.0_172-b01)
OpenJDK 64-Bit Server VM (Zulu 8.30.0.1-linux64) (build 25.172-b01, mixed mode)
$ docker version
Client:
Version: 18.05.0-ce
API version: 1.37
Go version: go1.9.5
Git commit: f150324
Built: Wed May 9 22:16:13 2018
OS/Arch: linux/amd64
Experimental: false
Orchestrator: swarm
Server:
Engine:
Version: 18.05.0-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.5
Git commit: f150324
Built: Wed May 9 22:14:23 2018
OS/Arch: linux/amd64
Experimental: false
When you simply run it with
docker run -it --rm -e MYSQL_ROOT_PASSWORD=blablubb -p 3306:3306 mysql:latest
you can't connect to the database plain with normal connection. Even with not the latest MySQL Workbench this is an issue, see screenshot.

We could use a workaround for this:
docker run -it --rm -e MYSQL_ROOT_PASSWORD=blablubb -p 3306:3306 mysql:latest --default-authentication-plugin=mysql_native_password
This does even work for the 5.7, 5.6 mysql docker image but it does not work for the 5.5 one.
So the workaround should only applied to mysql docker images with version >= 5.6. But we can't decide by using docker tags since the docker tags are free to change for everyone.
We need a check for the version of given docker image before starting it. We could simply launch one container before and parse the version but this might be a big performance issue then.
If you want to use mysql:8 as docker image or mysql:latest I would suggest to add the command --default-authentication-plugin=mysql_native_password to your MySqlContainer instance.
Thanks @StefanHufschmidt - I originally tried to start the container manually and connect to it using mysql CLI client and was under impression that it worked, but I must've messed something up (like starting the wrong container :roll_eyes:) as now I do get the same ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded like you.
Hopefully this ticket can still be used to provide the solution within Testcontainers that would make it work out-of-the-box.
I read in https://dev.mysql.com/doc/connectors/en/connector-j-reference-configuration-properties.html that you could set the defaultAuthenticationPlugin property on the jdbc url. I tried to set it to com.mysql.cj.protocol.a.authentication.MysqlNativePasswordPlugin (even though the doc (erroneously?) says it's the default) but it does not work. Has anyone explored this option already?
I'm also trying to run TC with MySQL 8.x. I tried adding the"--default-authentication-plugin=mysql_native_password" config but it just hangs till a timeout occurs. In the logs there's a mbind: Operation not permitted message printed but apparently it's not the problem and it's just a warning according to https://github.com/docker-library/mysql/issues/303
Has anyone succeeded in running MySQL 8.x with MySQLContainer?
FWIW this my log:
15:43:17.351 [tc-okhttp-stream-1806378373] INFO o.x.t.d.j.d.DatabaseContainerExecutor - STDERR: 2019-01-14T14:43:17.350505Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.13' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
15:43:17.378 [tc-okhttp-stream-1806378373] INFO o.x.t.d.j.d.DatabaseContainerExecutor - STDERR: 2019-01-14T14:43:17.377980Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060
15:43:17.440 [tc-okhttp-stream-1806378373] INFO o.x.t.d.j.d.DatabaseContainerExecutor - STDERR: mbind: Operation not permitted
15:44:59.807 [main] ERROR 🐳 [mysql:8] - Could not start container
org.rnorth.ducttape.TimeoutException: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
...
I did some more debugging last weekend, I am using Spring Boot and apparently if you add any property to your jdbc url (spring.datasource.url), it will not help as testcontainers doesn't seem to be using that url to test if the container is up and running.
apparently if you add any property to your jdbc url (spring.datasource.url), it will not help as testcontainers doesn't seem to be using that url to test if the container is up and running.
Note: I do use some property to the JDBC URL (jdbc:mysql://%s:%s/xwiki?useSSL=false) but this has always worked with MySQL 5.5, 5.7. Only problem I have is with MySQL 8, and I've added --default-authentication-plugin=mysql_native_password as suggested, using https://github.com/xwiki/xwiki-platform/blob/91edf322863811160bb9e78e1439641dfc9237bd/xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-docker/src/main/java/org/xwiki/test/docker/junit5/database/DatabaseContainerExecutor.java#L123
Cool thanks @rnorth ! Will tests as soon as the next TC version is released!
Most helpful comment
When you simply run it with

docker run -it --rm -e MYSQL_ROOT_PASSWORD=blablubb -p 3306:3306 mysql:latestyou can't connect to the database plain with normal connection. Even with not the latest MySQL Workbench this is an issue, see screenshot.
We could use a workaround for this:
docker run -it --rm -e MYSQL_ROOT_PASSWORD=blablubb -p 3306:3306 mysql:latest --default-authentication-plugin=mysql_native_passwordThis does even work for the 5.7, 5.6 mysql docker image but it does not work for the 5.5 one.
So the workaround should only applied to mysql docker images with version >= 5.6. But we can't decide by using docker tags since the docker tags are free to change for everyone.
We need a check for the version of given docker image before starting it. We could simply launch one container before and parse the version but this might be a big performance issue then.
If you want to use mysql:8 as docker image or mysql:latest I would suggest to add the command
--default-authentication-plugin=mysql_native_passwordto your MySqlContainer instance.