From 5e2730eb01850b785fe354561d524c239ed9c3f6 Mon Sep 17 00:00:00 2001 From: ohchanKyu Date: Mon, 28 Sep 2026 14:26:47 +0900 Subject: [PATCH] Recognize MARIADB_ALLOW_EMPTY_ROOT_PASSWORD in Docker Compose support MariaDbEnvironment checked for MARIADB_ALLOW_EMPTY_PASSWORD, which the official MariaDB image does not support. The documented variable is MARIADB_ALLOW_EMPTY_ROOT_PASSWORD. As a result, a compose service that used the documented variable started fine but Spring Boot failed with "No MariaDB password found". See gh-51870 Signed-off-by: ohchanKyu --- ...poseConnectionDetailsFactoryIntegrationTests.java | 7 +++++++ .../mariadb-with-empty-root-password-compose.yaml | 8 ++++++++ .../boot/jdbc/docker/compose/MariaDbEnvironment.java | 2 +- .../jdbc/docker/compose/MariaDbEnvironmentTests.java | 12 ++++++------ ...poseConnectionDetailsFactoryIntegrationTests.java | 7 +++++++ .../mariadb-with-empty-root-password-compose.yaml | 8 ++++++++ .../r2dbc/docker/compose/MariaDbEnvironment.java | 2 +- .../docker/compose/MariaDbEnvironmentTests.java | 12 ++++++------ 8 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 module/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mariadb-with-empty-root-password-compose.yaml create mode 100644 module/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mariadb-with-empty-root-password-compose.yaml diff --git a/module/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 04df58d4ea3..ea5d94ba504 100644 --- a/module/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-jdbc/src/dockerTest/java/org/springframework/boot/jdbc/docker/compose/MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -37,6 +37,13 @@ class MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests { assertConnectionDetails(connectionDetails); } + @DockerComposeTest(composeFile = "mariadb-with-empty-root-password-compose.yaml", image = TestImage.MARIADB) + void runWithEmptyRootPasswordCreatesConnectionDetails(JdbcConnectionDetails connectionDetails) { + assertThat(connectionDetails.getUsername()).isEqualTo("root"); + assertThat(connectionDetails.getPassword()).isEmpty(); + assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:mariadb://").endsWith("/mydatabase"); + } + private void assertConnectionDetails(JdbcConnectionDetails connectionDetails) { assertThat(connectionDetails.getUsername()).isEqualTo("myuser"); assertThat(connectionDetails.getPassword()).isEqualTo("secret"); diff --git a/module/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mariadb-with-empty-root-password-compose.yaml b/module/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mariadb-with-empty-root-password-compose.yaml new file mode 100644 index 00000000000..cd507b072f1 --- /dev/null +++ b/module/spring-boot-jdbc/src/dockerTest/resources/org/springframework/boot/jdbc/docker/compose/mariadb-with-empty-root-password-compose.yaml @@ -0,0 +1,8 @@ +services: + database: + image: '{imageName}' + ports: + - '3306' + environment: + - 'MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=yes' + - 'MARIADB_DATABASE=mydatabase' diff --git a/module/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironment.java b/module/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironment.java index 4225926950c..93763663ea7 100644 --- a/module/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironment.java +++ b/module/spring-boot-jdbc/src/main/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironment.java @@ -57,7 +57,7 @@ class MariaDbEnvironment { Assert.state(!env.containsKey("MARIADB_RANDOM_ROOT_PASSWORD"), "MARIADB_RANDOM_ROOT_PASSWORD is not supported"); Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported"); Assert.state(!env.containsKey("MARIADB_ROOT_PASSWORD_HASH"), "MARIADB_ROOT_PASSWORD_HASH is not supported"); - boolean allowEmpty = env.containsKey("MARIADB_ALLOW_EMPTY_PASSWORD") + boolean allowEmpty = env.containsKey("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD") || env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD"); String password = env.get("MARIADB_PASSWORD"); password = (password != null) ? password : env.get("MYSQL_PASSWORD"); diff --git a/module/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironmentTests.java b/module/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironmentTests.java index 54d872a6faf..583bb975a26 100644 --- a/module/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironmentTests.java +++ b/module/spring-boot-jdbc/src/test/java/org/springframework/boot/jdbc/docker/compose/MariaDbEnvironmentTests.java @@ -139,9 +139,9 @@ class MariaDbEnvironmentTests { } @Test - void getPasswordWhenHasNoPasswordAndMariadbAllowEmptyPassword() { + void getPasswordWhenHasNoPasswordAndMariadbAllowEmptyRootPassword() { MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + Map.of("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD", "true", "MARIADB_DATABASE", "db")); assertThat(environment.getPassword()).isEmpty(); } @@ -155,21 +155,21 @@ class MariaDbEnvironmentTests { @Test void getDatabaseWhenHasMariadbDatabase() { MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + Map.of("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD", "true", "MARIADB_DATABASE", "db")); assertThat(environment.getDatabase()).isEqualTo("db"); } @Test void getDatabaseWhenHasMysqlDatabase() { MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); + Map.of("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD", "true", "MYSQL_DATABASE", "db")); assertThat(environment.getDatabase()).isEqualTo("db"); } @Test void getDatabaseWhenHasMariadbAndMysqlDatabase() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db", "MYSQL_DATABASE", "otherdb")); + MariaDbEnvironment environment = new MariaDbEnvironment(Map.of("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD", "true", + "MARIADB_DATABASE", "db", "MYSQL_DATABASE", "otherdb")); assertThat(environment.getDatabase()).isEqualTo("db"); } diff --git a/module/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index aa4e418c677..dbc4418cd07 100644 --- a/module/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/module/spring-boot-r2dbc/src/dockerTest/java/org/springframework/boot/r2dbc/docker/compose/MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -39,6 +39,13 @@ class MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests { assertConnectionDetails(connectionDetails); } + @DockerComposeTest(composeFile = "mariadb-with-empty-root-password-compose.yaml", image = TestImage.MARIADB) + void runWithEmptyRootPasswordCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) { + ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions(); + assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=mariadb", "user=root"); + assertThat(connectionFactoryOptions.hasOption(ConnectionFactoryOptions.PASSWORD)).isFalse(); + } + private void assertConnectionDetails(R2dbcConnectionDetails connectionDetails) { ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions(); assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=mariadb", diff --git a/module/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mariadb-with-empty-root-password-compose.yaml b/module/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mariadb-with-empty-root-password-compose.yaml new file mode 100644 index 00000000000..cd507b072f1 --- /dev/null +++ b/module/spring-boot-r2dbc/src/dockerTest/resources/org/springframework/boot/r2dbc/docker/compose/mariadb-with-empty-root-password-compose.yaml @@ -0,0 +1,8 @@ +services: + database: + image: '{imageName}' + ports: + - '3306' + environment: + - 'MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=yes' + - 'MARIADB_DATABASE=mydatabase' diff --git a/module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironment.java b/module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironment.java index 436647aef31..13534005f9a 100644 --- a/module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironment.java +++ b/module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironment.java @@ -57,7 +57,7 @@ class MariaDbEnvironment { Assert.state(!env.containsKey("MARIADB_RANDOM_ROOT_PASSWORD"), "MARIADB_RANDOM_ROOT_PASSWORD is not supported"); Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported"); Assert.state(!env.containsKey("MARIADB_ROOT_PASSWORD_HASH"), "MARIADB_ROOT_PASSWORD_HASH is not supported"); - boolean allowEmpty = env.containsKey("MARIADB_ALLOW_EMPTY_PASSWORD") + boolean allowEmpty = env.containsKey("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD") || env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD"); String password = env.get("MARIADB_PASSWORD"); password = (password != null) ? password : env.get("MYSQL_PASSWORD"); diff --git a/module/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironmentTests.java b/module/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironmentTests.java index 169af621b88..b6691e1e9f8 100644 --- a/module/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironmentTests.java +++ b/module/spring-boot-r2dbc/src/test/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironmentTests.java @@ -139,9 +139,9 @@ class MariaDbEnvironmentTests { } @Test - void getPasswordWhenHasNoPasswordAndMariadbAllowEmptyPassword() { + void getPasswordWhenHasNoPasswordAndMariadbAllowEmptyRootPassword() { MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + Map.of("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD", "true", "MARIADB_DATABASE", "db")); assertThat(environment.getPassword()).isEmpty(); } @@ -155,21 +155,21 @@ class MariaDbEnvironmentTests { @Test void getDatabaseWhenHasMariadbDatabase() { MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db")); + Map.of("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD", "true", "MARIADB_DATABASE", "db")); assertThat(environment.getDatabase()).isEqualTo("db"); } @Test void getDatabaseWhenHasMysqlDatabase() { MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db")); + Map.of("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD", "true", "MYSQL_DATABASE", "db")); assertThat(environment.getDatabase()).isEqualTo("db"); } @Test void getDatabaseWhenHasMariadbAndMysqlDatabase() { - MariaDbEnvironment environment = new MariaDbEnvironment( - Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db", "MYSQL_DATABASE", "otherdb")); + MariaDbEnvironment environment = new MariaDbEnvironment(Map.of("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD", "true", + "MARIADB_DATABASE", "db", "MYSQL_DATABASE", "otherdb")); assertThat(environment.getDatabase()).isEqualTo("db"); }