Skip to content

Commit e66745a

Browse files
pkostrzewasnicoll
authored andcommitted
Improve FailureAnalyzer for embedded datasource
See gh-11953
1 parent 2b9006b commit e66745a

File tree

4 files changed

+71
-56
lines changed

4 files changed

+71
-56
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBeanCreationFailureAnalyzer.java

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,72 @@
1616

1717
package org.springframework.boot.autoconfigure.jdbc;
1818

19+
import java.util.Objects;
20+
1921
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.DataSourceBeanCreationException;
2022
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
2123
import org.springframework.boot.diagnostics.FailureAnalysis;
24+
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
25+
import org.springframework.context.EnvironmentAware;
26+
import org.springframework.core.env.Environment;
27+
import org.springframework.util.ObjectUtils;
28+
import org.springframework.util.StringUtils;
2229

2330
/**
2431
* An {@link AbstractFailureAnalyzer} for failures caused by a
2532
* {@link DataSourceBeanCreationException}.
2633
*
2734
* @author Andy Wilkinson
35+
* @author Patryk Kostrzewa
2836
*/
2937
class DataSourceBeanCreationFailureAnalyzer
30-
extends AbstractFailureAnalyzer<DataSourceBeanCreationException> {
38+
extends AbstractFailureAnalyzer<DataSourceBeanCreationException>
39+
implements EnvironmentAware {
40+
41+
private Environment environment;
3142

3243
@Override
3344
protected FailureAnalysis analyze(Throwable rootFailure,
3445
DataSourceBeanCreationException cause) {
35-
String message = cause.getMessage();
36-
String description = message.substring(0, message.indexOf('.')).trim();
37-
String action = message.substring(message.indexOf('.') + 1).trim();
38-
return new FailureAnalysis(description, action, cause);
46+
return getFailureAnalysis(cause);
47+
}
48+
49+
@Override
50+
public void setEnvironment(Environment environment) {
51+
this.environment = environment;
3952
}
4053

54+
private FailureAnalysis getFailureAnalysis(DataSourceBeanCreationException cause) {
55+
56+
final EmbeddedDatabaseConnection connection = cause.getConnection();
57+
final String action;
58+
59+
if (EmbeddedDatabaseConnection.NONE == connection) {
60+
action = "If you want an embedded database "
61+
+ "please put a supported one on the classpath.";
62+
}
63+
else {
64+
action = "If you have database settings to be loaded "
65+
+ "from a particular profile you may need to activate it"
66+
+ getActiveProfiles();
67+
}
68+
return new FailureAnalysis(cause.getMessage(), action, cause);
69+
}
70+
71+
private String getActiveProfiles() {
72+
73+
final StringBuilder message = new StringBuilder();
74+
if (Objects.nonNull(this.environment)) {
75+
String[] profiles = this.environment.getActiveProfiles();
76+
if (ObjectUtils.isEmpty(profiles)) {
77+
message.append(" (no profiles are currently active).");
78+
}
79+
else {
80+
message.append(" (the profiles ");
81+
message.append(StringUtils.arrayToCommaDelimitedString(profiles));
82+
message.append(" are currently active).");
83+
}
84+
}
85+
return message.toString();
86+
}
4187
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java

Lines changed: 17 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,8 @@
3232
import org.springframework.boot.jdbc.DataSourceInitializationMode;
3333
import org.springframework.boot.jdbc.DatabaseDriver;
3434
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
35-
import org.springframework.context.EnvironmentAware;
36-
import org.springframework.core.env.Environment;
3735
import org.springframework.util.Assert;
3836
import org.springframework.util.ClassUtils;
39-
import org.springframework.util.ObjectUtils;
4037
import org.springframework.util.StringUtils;
4138

4239
/**
@@ -47,16 +44,15 @@
4744
* @author Stephane Nicoll
4845
* @author Benedikt Ritter
4946
* @author Eddú Meléndez
47+
* @author Patryk Kostrzewa
5048
* @since 1.1.0
5149
*/
5250
@ConfigurationProperties(prefix = "spring.datasource")
5351
public class DataSourceProperties
54-
implements BeanClassLoaderAware, EnvironmentAware, InitializingBean {
52+
implements BeanClassLoaderAware, InitializingBean {
5553

5654
private ClassLoader classLoader;
5755

58-
private Environment environment;
59-
6056
/**
6157
* Name of the datasource. Default to "testdb" when using an embedded database.
6258
*/
@@ -166,11 +162,6 @@ public void setBeanClassLoader(ClassLoader classLoader) {
166162
this.classLoader = classLoader;
167163
}
168164

169-
@Override
170-
public void setEnvironment(Environment environment) {
171-
this.environment = environment;
172-
}
173-
174165
@Override
175166
public void afterPropertiesSet() throws Exception {
176167
this.embeddedDatabaseConnection = EmbeddedDatabaseConnection
@@ -244,8 +235,9 @@ public String determineDriverClassName() {
244235
driverClassName = this.embeddedDatabaseConnection.getDriverClassName();
245236
}
246237
if (!StringUtils.hasText(driverClassName)) {
247-
throw new DataSourceBeanCreationException(this.embeddedDatabaseConnection,
248-
this.environment, "driver class");
238+
throw new DataSourceBeanCreationException(
239+
"Failed to determine a suitable driver class",
240+
this.embeddedDatabaseConnection);
249241
}
250242
return driverClassName;
251243
}
@@ -290,8 +282,9 @@ public String determineUrl() {
290282
String url = (databaseName == null ? null
291283
: this.embeddedDatabaseConnection.getUrl(databaseName));
292284
if (!StringUtils.hasText(url)) {
293-
throw new DataSourceBeanCreationException(this.embeddedDatabaseConnection,
294-
this.environment, "url");
285+
throw new DataSourceBeanCreationException(
286+
"Failed to determine suitable jdbc url",
287+
this.embeddedDatabaseConnection);
295288
}
296289
return url;
297290
}
@@ -522,37 +515,17 @@ public void setProperties(Map<String, String> properties) {
522515

523516
static class DataSourceBeanCreationException extends BeanCreationException {
524517

525-
DataSourceBeanCreationException(EmbeddedDatabaseConnection connection,
526-
Environment environment, String property) {
527-
super(getMessage(connection, environment, property));
528-
}
518+
private final EmbeddedDatabaseConnection connection;
529519

530-
private static String getMessage(EmbeddedDatabaseConnection connection,
531-
Environment environment, String property) {
532-
StringBuilder message = new StringBuilder();
533-
message.append("Cannot determine embedded database " + property
534-
+ " for database type " + connection + ". ");
535-
message.append("If you want an embedded database please put a supported "
536-
+ "one on the classpath. ");
537-
message.append("If you have database settings to be loaded from a "
538-
+ "particular profile you may need to active it");
539-
if (environment != null) {
540-
String[] profiles = environment.getActiveProfiles();
541-
if (ObjectUtils.isEmpty(profiles)) {
542-
message.append(" (no profiles are currently active)");
543-
}
544-
else {
545-
message.append(" (the profiles \""
546-
+ StringUtils.arrayToCommaDelimitedString(
547-
environment.getActiveProfiles())
548-
+ "\" are currently active)");
549-
550-
}
551-
}
552-
message.append(".");
553-
return message.toString();
520+
DataSourceBeanCreationException(String message,
521+
EmbeddedDatabaseConnection connection) {
522+
523+
super(message);
524+
this.connection = connection;
554525
}
555526

527+
public EmbeddedDatabaseConnection getConnection() {
528+
return this.connection;
529+
}
556530
}
557-
558531
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBeanCreationFailureAnalyzerTests.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,8 @@ public class DataSourceBeanCreationFailureAnalyzerTests {
4141
@Test
4242
public void failureAnalysisIsPerformed() {
4343
FailureAnalysis failureAnalysis = performAnalysis(TestConfiguration.class);
44-
assertThat(failureAnalysis.getDescription()).isEqualTo(
45-
"Cannot determine embedded database driver class for database type NONE");
46-
assertThat(failureAnalysis.getAction()).isEqualTo("If you want an embedded "
47-
+ "database please put a supported one on the classpath. If you have "
48-
+ "database settings to be loaded from a particular profile you may "
49-
+ "need to active it (no profiles are currently active).");
44+
assertThat(failureAnalysis.getDescription()).isEqualTo("Failed to determine a suitable driver class");
45+
assertThat(failureAnalysis.getAction()).isEqualTo("If you want an embedded database please put a supported one on the classpath.");
5046
}
5147

5248
private FailureAnalysis performAnalysis(Class<?> configuration) {

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourcePropertiesTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public void determineUrlWithNoEmbeddedSupport() throws Exception {
7272
new FilteredClassLoader("org.h2", "org.apache.derby", "org.hsqldb"));
7373
properties.afterPropertiesSet();
7474
this.thrown.expect(DataSourceProperties.DataSourceBeanCreationException.class);
75-
this.thrown.expectMessage("Cannot determine embedded database url");
75+
this.thrown.expectMessage("Failed to determine suitable jdbc url");
7676
properties.determineUrl();
7777
}
7878

0 commit comments

Comments
 (0)