Improve DataSourceProperties exception messages

Update DataSourceProperties exceptions to include a less misleading
message. Errors message now note that you may need to add an embedded
database to the classpath or active a profile to pickup specific
settings.

Fixes gh-4012
This commit is contained in:
Phillip Webb 2015-09-24 10:24:08 -07:00
parent 44c122307e
commit 06f3202c68
1 changed files with 52 additions and 13 deletions

View File

@ -26,8 +26,11 @@ import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -39,10 +42,15 @@ import org.springframework.util.StringUtils;
* @since 1.1.0 * @since 1.1.0
*/ */
@ConfigurationProperties(prefix = DataSourceProperties.PREFIX) @ConfigurationProperties(prefix = DataSourceProperties.PREFIX)
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean { public class DataSourceProperties implements BeanClassLoaderAware, EnvironmentAware,
InitializingBean {
public static final String PREFIX = "spring.datasource"; public static final String PREFIX = "spring.datasource";
private ClassLoader classLoader;
private Environment environment;
/** /**
* Name of the datasource. * Name of the datasource.
*/ */
@ -74,8 +82,6 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
*/ */
private String password; private String password;
private ClassLoader classLoader;
/** /**
* JNDI location of the datasource. Class, url, username & password are ignored when * JNDI location of the datasource. Class, url, username & password are ignored when
* set. * set.
@ -126,6 +132,11 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
this.classLoader = classLoader; this.classLoader = classLoader;
} }
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
this.embeddedDatabaseConnection = EmbeddedDatabaseConnection this.embeddedDatabaseConnection = EmbeddedDatabaseConnection
@ -165,11 +176,8 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
} }
if (!StringUtils.hasText(driverClassName)) { if (!StringUtils.hasText(driverClassName)) {
throw new BeanCreationException( throw new DataSourceBeanCreationException(this.embeddedDatabaseConnection,
"Cannot determine embedded database driver class for database type " this.environment, "driver class");
+ this.embeddedDatabaseConnection
+ ". If you want an embedded "
+ "database please put a supported one on the classpath.");
} }
return driverClassName; return driverClassName;
} }
@ -184,11 +192,8 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
} }
String url = this.embeddedDatabaseConnection.getUrl(); String url = this.embeddedDatabaseConnection.getUrl();
if (!StringUtils.hasText(url)) { if (!StringUtils.hasText(url)) {
throw new BeanCreationException( throw new DataSourceBeanCreationException(this.embeddedDatabaseConnection,
"Cannot determine embedded database url for database type " this.environment, "url");
+ this.embeddedDatabaseConnection
+ ". If you want an embedded "
+ "database please put a supported one on the classpath.");
} }
return url; return url;
} }
@ -340,4 +345,38 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
} }
private static class DataSourceBeanCreationException extends BeanCreationException {
public DataSourceBeanCreationException(EmbeddedDatabaseConnection connection,
Environment environment, String property) {
super(getMessage(connection, environment, property));
}
private static String getMessage(EmbeddedDatabaseConnection connection,
Environment environment, String property) {
StringBuilder message = new StringBuilder();
message.append("Cannot determine embedded database " + property
+ " for database type " + connection + ". ");
message.append("If you want an embedded database please put a supported "
+ "one on the classpath. ");
message.append("If you have database settings to be loaded from a "
+ "particular profile you may need to active it");
if (environment != null) {
String[] profiles = environment.getActiveProfiles();
if (ObjectUtils.isEmpty(profiles)) {
message.append(" (no profiles are currently active)");
}
else {
message.append(" (the profiles \""
+ StringUtils.arrayToCommaDelimitedString(environment
.getActiveProfiles()) + "\" are currently active)");
}
}
message.append(".");
return message.toString();
}
}
} }