Michael
Michael

Reputation: 591

Why is Environment variable always null when reading from properties file?

I am new to using application.properties and am struggling because Environment is always null. I have followed numerous examples such as the accepted answer shown on SO HERE; however, I keep getting the error message showing below. This is a Spring application and I know I don't actually need to go through this manual process per the article HERE. However, I have to show how to connect manually using the properties file. Where am I going wrong? Effectively, I want to hide my database credentials in application.properties and then read them into something like DriverManager.getConnection(env.getProperty("URL"), env.getProperty("USERNAME", env.getProperty("PASSWORD");

Attempting to use Environment:

@Component
@PropertySource("classpath:application.properties")
public class OpenConnection {
    private volatile Connection con;
    @Autowired
    private Environment env;


    public OpenConnection() {
    }

    @Bean
    public Connection getInstance() {
        try {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
            dataSource.setUrl(env.getProperty("spring.datasource.url"));
            dataSource.setUsername(env.getProperty("spring.datasource.username"));
            dataSource.setPassword(env.getProperty("spring.datasource.password"));
            con = dataSource.getConnection();
        } catch (SQLException e) {
            handleException(e);
        }

        return con;
    }

application.properties

# MySQL
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/rentalportfolio?useTimezone=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

Error message

java.lang.NullPointerException: null
    at com.crd.carrental.database.connectionoperations.OpenConnection.getInstance(OpenConnection.java:43) ~[classes/:na]
    at com.crd.carrental.database.selectoperations.SelectExistingReservation.<init>(SelectExistingReservation.java:24) ~[classes/:na]
    at com.crd.carrental.controllers.ExistingReservationController.lookupReservationId(ExistingReservationController.java:24) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_261]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_261]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_261]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_261]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171) ~[spring-messaging-5.3.3.jar:5.3.3]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120) ~[spring-messaging-5.3.3.jar:5.3.3]
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:565) [spring-messaging-5.3.3.jar:5.3.3]
    at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:511) [spring-messaging-5.3.3.jar:5.3.3]
    at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:94) [spring-messaging-5.3.3.jar:5.3.3]
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:520) [spring-messaging-5.3.3.jar:5.3.3]
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:454) [spring-messaging-5.3.3.jar:5.3.3]
    at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:144) [spring-messaging-5.3.3.jar:5.3.3]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_261]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_261]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_261]

Upvotes: 1

Views: 3307

Answers (2)

mehowthe
mehowthe

Reputation: 841

I think that the problem is that you are using @Component on your OpenConnection rather than @Configuration

Here you can find some more examples, how to use properties in your Spring application

Upvotes: 1

Chris Savory
Chris Savory

Reputation: 2755

I recommend removing this OpenConnection class and let SpringBoot create your datasource for you on start up.

If you really want to create it yourself, check the docs. Here is an example:

@Configuration
public class DataSourceConfiguration {

   @Bean
   @ConfigurationProperties("spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }
}

Upvotes: 1

Related Questions