Search code examples
spring-bootautowiredspring-boot-actuatorspring-boot-testspring-boot-maven-plugin

Getting NullPointerException when tried to read @Autowired configuration object


I am trying to read some properties from application.properties. I have created a configuration class with @Component and @ConfigurationProperties annotations.

When I am trying to access the configuration from a controller class, its working fine. But when I am trying to access the configuration from one component class, its throwing a null pointer exception.

Following are the application.properties and classes.

application.properties

elasticsearch.ip=localhost

InputManagementController.java

@RestController
public class InputManagementController {


    @Autowired
    private Configuration configuration;

    @GetMapping("/crawler/start")
    public String start(){
        try{

            System.out.println(configuration.getIp()); ----> getting value localhost
            ElasticsearchInterface es=new ElasticsearchInterface();
            es.getInputs();
        }catch (Exception e){
            e.printStackTrace();
        }
        return "started";
    }
}

ElasticsearchInterface.java

@Component
public class ElasticsearchInterface {


    @Autowired
    private Configuration configuration;

    public List<Map<String, Object>> getInputs() {
            System.out.println(configuration.getIp()); ---> getting java.lang.NullPointerException here
        return null;

    }

}

Configuration.java

@Component
@ConfigurationProperties("elasticsearch")
public class Configuration {

    private String ip;
    private int port;
    private String cluster;

    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }

}

Solution

  • A - How To Read Custom Property From application.properties In Spring Boot

    A-1) Application Properties file

    On of the default location of application.properties file is src/main/resources. Create this folder and also this file. Assuming your scenario, put the following properties inside application.properties file;

    myconfig.ip=192.168.166.42
    myconfig.port=8090
    

    A-2) Configuration Class : AppConfig

    In order to read the properties file, you need a class with @Configuration annotation. You need appropriate fields with @Value annotation for all the properties that you need to read. In addition, also you need the getter methods for these fields marked with @Value annotation. Please note that naming this class as "Configuration" is a very bad choice because there is also an annotation with the same name, thus I name it as "AppConfig"

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class AppConfig {
    
        @Value("${myconfig.ip}")
        private String ip;
    
        @Value("${myconfig.port}")
        private int port;
    
        public String getIp() {
            return ip;
        }
    
        public int getPort() {
            return port;
        }
    
    }
    

    A-3) Demo

    Then you create a fields of this AppConfig class which is written above, and mark it with @Autowired annotation. Then you can read the properties files easily;

    @RestController
    @RequestMapping("/")
    public class InputManagementController {
    
        @Autowired
        private AppConfig config;
    
        @RequestMapping("/test")
        public String test() {
            return String.format(
                    "Configuration Parameters: Port: %s, Ip: %s", 
                    config.getPort(),
                    config.getIp()
            );
        }
    
    }
    

    A-4) Output

    enter image description here

    B - Solution To Problem

    B-1) InputManagementController.java

    @RestController
    public class InputManagementController {
    
        @Autowired
        private AppConfig configuration;
    
        @Autowired
        private ElasticSearchInterface elasticSearchInterface;
    
        @GetMapping("/crawler/start")
        public String start() {
            try {
    
                System.out.println(configuration.getIp());
                es.getInputs();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "started";
        }
    }
    

    B-2) ElasticSearchInterface.java

    @Component
    public class ElasticSearchInterface {
    
        @Autowired
        private AppConfig configuration;
    
        public List<Map<String, Object>> getInputs() {
            System.out.println(configuration.getIp());
    
            return null;
        }
    
    }
    

    B-3) AppConfig.java

    @Configuration
    public class AppConfig {
    
        @Value("${myconfig.ip}")
        private String ip;
    
        @Value("${myconfig.port}")
        private int port;
    
        public String getIp() {
            return ip;
        }
    
        public int getPort() {
            return port;
        }
    
    }