Reputation: 452
I'm attempting to retrieve properties loaded from a .yml file by autowiring an Environment variable, but I'm getting a null pointer exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/example/AppConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.NullPointerException
I want to programatically create a DataSource bean while keeping the details (username, password, host, etc) in a configuration file. This is my setup at the moment:
@SpringBootApplication
@ImportResource({"classpath:controllers.xml"})
public class WebApplication{
public static void main(String[] args){
SpringApplication.run(WebApplication.class, args);
}
}
server:
port: 8080
database:
host: localhost
instance: db_instance
port: 3036
user: root
password: passkey
@Configuration
public class AppConfig {
@Autowired
private Environment environment;
@Bean
public DataSource dataSource() {
String url = "jdbc:mysql://" +
environment.getProperty("database.host") +
":" + environment.getProperty("database.port") +
"/" + environment.getProperty("database.instance") +
"?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
return DataSourceBuilder.create()
.driverClassName("com.mysql.jdbc.Driver")
.url(url)
.username(environment.getProperty("database.user"))
.password(environment.getProperty("database.password"))
.build();
}
}
I'm not partial to either the .yml file format or using the Environment variable. If there is a different/better way to go about getting the data from the .yml file (or some other file format), I'm willing to try it.
Upvotes: 1
Views: 4394
Reputation: 219
Not really sure what is there in controllers.xml . But I was able to fetch environment variable and use it.
I placed the properties you mentioned in application.yml in /src/main/resources
I used Spring boot-2.1.9 version to make it work and below is my pom.xml-
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>stackoverflow</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<name>stackoverflow</name>
<description>stackoverflow</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>ojo-snapshots</id>
<name>OJO Snapshots</name>
<url>https://oss.jfrog.org/artifactory/libs-snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
Upvotes: 0
Reputation: 27018
There are many ways to do this.
Since you are using Springboot, you do not have to create a
Datasource explicitly like this(If you do so, you are missing out on one of the main features of springboot). If you declare the parameters in
properties/yml with right keys, Springboot with Autoconfigure this
for you.
Search for spring.datasource......
here
If you wish to do this on your own, then You can autowire all the variables in properties/yml file into a Bean using
ConfigurationProperties
then use this bean as method parameter in
your bean creation method.
check this out
@Value{}
in your AppConfig class and use it in your Datasource creation method.Upvotes: 4