Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MySQLContainer unable to run MySQL 8 #736

Closed
vpavic opened this issue Jun 6, 2018 · 8 comments · Fixed by #1470
Closed

MySQLContainer unable to run MySQL 8 #736

vpavic opened this issue Jun 6, 2018 · 8 comments · Fixed by #1470

Comments

@vpavic
Copy link
Contributor

vpavic commented Jun 6, 2018

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
@StefanHufschmidt
Copy link
Contributor

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.
screenshot_2018-06-08_15-49-52

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.

@vpavic
Copy link
Contributor Author

vpavic commented Jun 8, 2018

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 🙄) 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.

@francescopeloi
Copy link

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?

@vmassol
Copy link
Contributor

vmassol commented Jan 14, 2019

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 docker-library/mysql#303

Has anyone succeeded in running MySQL 8.x with MySQLContainer?

@vmassol
Copy link
Contributor

vmassol commented Jan 14, 2019

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
...

@francescopeloi
Copy link

francescopeloi commented Jan 14, 2019

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.

@vmassol
Copy link
Contributor

vmassol commented Jan 14, 2019

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

rnorth pushed a commit that referenced this issue May 15, 2019
rnorth pushed a commit that referenced this issue May 15, 2019
rnorth pushed a commit that referenced this issue May 15, 2019
rnorth pushed a commit that referenced this issue May 15, 2019
rnorth added a commit that referenced this issue May 27, 2019
Amend default MySQL connection parameters for MySQL 5 - 8 compatibility
Fixes #736
@xwikiorgci
Copy link

Cool thanks @rnorth ! Will tests as soon as the next TC version is released!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants