Make EmbeddedDatabaseConnection GraalVM compatible

Without those changes, if @AutoConfigureTestDatabase is used, the
native image build process fails with:

  EmbeddedDatabaseConnection was unintentionally initialized at build
  time.

Closes gh-32865
This commit is contained in:
Moritz Halbritter
2022-10-26 13:32:31 +02:00
parent eeac08e50e
commit 1f0cf1ac2b

View File

@@ -20,7 +20,6 @@ import java.sql.Connection;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Locale; import java.util.Locale;
import java.util.function.Predicate;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.sql.DataSource; import javax.sql.DataSource;
@@ -39,6 +38,7 @@ import org.springframework.util.ClassUtils;
* @author Dave Syer * @author Dave Syer
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Nidhi Desai * @author Nidhi Desai
* @author Moritz Halbritter
* @since 1.0.0 * @since 1.0.0
* @see #get(ClassLoader) * @see #get(ClassLoader)
*/ */
@@ -47,49 +47,35 @@ public enum EmbeddedDatabaseConnection {
/** /**
* No Connection. * No Connection.
*/ */
NONE(null, null, null, (url) -> false), NONE(null),
/** /**
* H2 Database Connection. * H2 Database Connection.
*/ */
H2(EmbeddedDatabaseType.H2, DatabaseDriver.H2.getDriverClassName(), H2("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"),
"jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE", (url) -> url.contains(":h2:mem")),
/** /**
* Derby Database Connection. * Derby Database Connection.
*/ */
DERBY(EmbeddedDatabaseType.DERBY, DatabaseDriver.DERBY.getDriverClassName(), "jdbc:derby:memory:%s;create=true", DERBY("jdbc:derby:memory:%s;create=true"),
(url) -> true),
/** /**
* HSQL Database Connection. * HSQL Database Connection.
* @since 2.4.0 * @since 2.4.0
*/ */
HSQLDB(EmbeddedDatabaseType.HSQL, DatabaseDriver.HSQLDB.getDriverClassName(), "org.hsqldb.jdbcDriver", HSQLDB("org.hsqldb.jdbcDriver", "jdbc:hsqldb:mem:%s");
"jdbc:hsqldb:mem:%s", (url) -> url.contains(":hsqldb:mem:"));
private final EmbeddedDatabaseType type;
private final String driverClass;
private final String alternativeDriverClass; private final String alternativeDriverClass;
private final String url; private final String url;
private final Predicate<String> embeddedUrl; EmbeddedDatabaseConnection(String url) {
this(null, url);
EmbeddedDatabaseConnection(EmbeddedDatabaseType type, String driverClass, String url,
Predicate<String> embeddedUrl) {
this(type, driverClass, null, url, embeddedUrl);
} }
EmbeddedDatabaseConnection(EmbeddedDatabaseType type, String driverClass, String fallbackDriverClass, String url, EmbeddedDatabaseConnection(String fallbackDriverClass, String url) {
Predicate<String> embeddedUrl) {
this.type = type;
this.driverClass = driverClass;
this.alternativeDriverClass = fallbackDriverClass; this.alternativeDriverClass = fallbackDriverClass;
this.url = url; this.url = url;
this.embeddedUrl = embeddedUrl;
} }
/** /**
@@ -97,7 +83,13 @@ public enum EmbeddedDatabaseConnection {
* @return the driver class name * @return the driver class name
*/ */
public String getDriverClassName() { public String getDriverClassName() {
return this.driverClass; // See https://github.com/spring-projects/spring-boot/issues/32865
return switch (this) {
case NONE -> null;
case H2 -> DatabaseDriver.H2.getDriverClassName();
case DERBY -> DatabaseDriver.DERBY.getDriverClassName();
case HSQLDB -> DatabaseDriver.HSQLDB.getDriverClassName();
};
} }
/** /**
@@ -105,7 +97,13 @@ public enum EmbeddedDatabaseConnection {
* @return the database type * @return the database type
*/ */
public EmbeddedDatabaseType getType() { public EmbeddedDatabaseType getType() {
return this.type; // See https://github.com/spring-projects/spring-boot/issues/32865
return switch (this) {
case NONE -> null;
case H2 -> EmbeddedDatabaseType.H2;
case DERBY -> EmbeddedDatabaseType.DERBY;
case HSQLDB -> EmbeddedDatabaseType.HSQL;
};
} }
/** /**
@@ -119,12 +117,18 @@ public enum EmbeddedDatabaseConnection {
} }
boolean isEmbeddedUrl(String url) { boolean isEmbeddedUrl(String url) {
return this.embeddedUrl.test(url); // See https://github.com/spring-projects/spring-boot/issues/32865
return switch (this) {
case NONE -> false;
case H2 -> url.contains(":h2:mem");
case DERBY -> true;
case HSQLDB -> url.contains(":hsqldb:mem:");
};
} }
boolean isDriverCompatible(String driverClass) { boolean isDriverCompatible(String driverClass) {
return (driverClass != null return (driverClass != null
&& (driverClass.equals(this.driverClass) || driverClass.equals(this.alternativeDriverClass))); && (driverClass.equals(getDriverClassName()) || driverClass.equals(this.alternativeDriverClass)));
} }
/** /**