Helo I have been trying to connect to a database with Spring Boot for a while and I keep getting the error:
java.sql.SQLException: The url cannot be null
I am not sure what is it that I am doing wrong. The reason I am trying to get the configuration like this is because I want to use the encoded password for the database.
This is what my files look like:
DataConfig.java
@Configuration
public class DataConfig {
@Autowired
private Environment env;
@Configuration
@Profile(value = "dev")
public class DevPlaceHolderConfig {
@Bean
DataSource dataSource() {
return DataSourceBuilder
.create()
.username(env.getProperty("spring.datasource.username"))
.password(env.getProperty("spring.datasource.password"))
.url(env.getProperty("spring.datasource.url"))
.driverClassName(env.getProperty("spring.datasource.driver-class-name"))
.build();
}
}
@Configuration
@Profile(value = "prod")
public class ProdPlaceHolderConfig {
@Bean
DataSource dataSource() {
return DataSourceBuilder
.create()
.username(env.getProperty("spring.datasource.username"))
.password(env.getProperty("spring.datasource.password"))
.url(env.getProperty("spring.datasource.url"))
.driverClassName(env.getProperty("spring.datasource.driver-class-name"))
.build();
}
}
}
EncryptorConfig.java
@Configuration
public class EncryptorConfig {
@Bean
public EnvironmentStringPBEConfig environmentVariablesConfiguration() {
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
config.setAlgorithm("PBEWithMD5AndDES");
config.setPasswordEnvName("APP_ENCRYPTION_PASSWORD");
return config;
}
@Bean
public PooledPBEStringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setConfig(environmentVariablesConfiguration());
return encryptor;
}
}
application.yml
spring:
profiles:
active: prod
output:
ansi:
enabled: always
---
spring:
profiles: dev
application:
name: App-Dev
datasource:
url: jdbc:mysql://localhost:3306/database?useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
jpa:
show-sql: true
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
server:
port: 8080
---
spring:
profiles: prod
application:
name: App-Prod
datasource:
url: jdbc:mysql://localhost:3306/database?useSSL=false
username: root
password: ENC(/98CfxmsjKBW5oZsLkLlmw==)
driver-class-name: com.mysql.jdbc.Driver
jpa:
show-sql: true
hibernate:
ddl-auto: none
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
server:
port: 3000
Here is the stack trace
2017-09-04 09:20:02.476 INFO 18128 --- [ main] com.vir.VirBackendApplication : The following profiles are active: prod
2017-09-04 09:20:02.536 INFO 18128 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1ebd319f: startup date [Mon Sep 04 09:20:02 EDT 2017]; root of context hierarchy
2017-09-04 09:20:03.479 INFO 18128 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=com.vir.config.DataConfig$ProdPlaceHolderConfig; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/vir/config/DataConfig$ProdPlaceHolderConfig.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=com.vir.config.EncryptorConfig$ProdPlaceHolderConfig; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/vir/config/EncryptorConfig$ProdPlaceHolderConfig.class]]
2017-09-04 09:20:03.898 INFO 18128 --- [ main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2017-09-04 09:20:04.112 INFO 18128 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$55ffc8cc] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-09-04 09:20:04.421 INFO 18128 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 5000 (http)
2017-09-04 09:20:04.431 INFO 18128 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2017-09-04 09:20:04.432 INFO 18128 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.16
2017-09-04 09:20:04.589 INFO 18128 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-09-04 09:20:04.589 INFO 18128 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2055 ms
2017-09-04 09:20:04.764 INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2017-09-04 09:20:04.769 INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-09-04 09:20:04.769 INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-09-04 09:20:04.769 INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-09-04 09:20:04.769 INFO 18128 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2017-09-04 09:20:04.817 INFO 18128 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.0.12.Final}
2017-09-04 09:20:04.820 INFO 18128 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2017-09-04 09:20:04.821 INFO 18128 --- [ main] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2017-09-04 09:20:04.967 WARN 18128 --- [ main] o.a.tomcat.jdbc.pool.PooledConnection : Not loading a JDBC driver as driverClassName property is null.
2017-09-04 09:20:04.978 ERROR 18128 --- [ main] o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.
java.sql.SQLException: The url cannot be null
at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.8.0_144]
at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.8.0_144]
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:308) ~[tomcat-jdbc-8.5.16.jar:na]
at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203) ~[tomcat-jdbc-8.5.16.jar:na]
at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:735) [tomcat-jdbc-8.5.16.jar:na]
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:667) [tomcat-jdbc-8.5.16.jar:na]
at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:482) [tomcat-jdbc-8.5.16.jar:na]
at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154) [tomcat-jdbc-8.5.16.jar:na]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) [tomcat-jdbc-8.5.16.jar:na]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) [tomcat-jdbc-8.5.16.jar:na]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131) [tomcat-jdbc-8.5.16.jar:na]
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:326) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:366) [spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.DatabaseLookup.getDatabase(DatabaseLookup.java:72) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties.determineDatabase(JpaProperties.java:139) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.jpaVendorAdapter(JpaBaseConfiguration.java:105) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$bf862cec.CGLIB$jpaVendorAdapter$9(<generated>) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$bf862cec$$FastClassBySpringCGLIB$$3d2e4b4f.invoke(<generated>) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) [spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$bf862cec.jpaVendorAdapter(<generated>) [spring-boot-autoconfigure-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_144]
Ok so it took me a while but this is how I solved my issues; which turned out to be a few.
So now my application.yml file looks like bellow, and APP_ENCRYPTION_PASSWORD is an environment variable holding the encryption password.
Also create private variables and bind them with a @Value() annotation. Also add the @EnableEncryptableProperties to the class.
DataConfig.java
And that's it it solved all my problems.