Environement is Null when I try to Autowire

10,086
package com.template.config;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Configuration;import     
org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource({ "classpath:/properties/email_${environment}.properties" })
@PropertySource({ "classpath:/properties/appconfig.properties" })
@PropertySource({ "classpath:/properties/ApplicationResources.properties" })
@PropertySource({ "classpath:/properties/Database_${environment}.properties"    

})
@PropertySource({ "classpath:/properties/log4j.properties" })
@PropertySource({ "classpath:/properties/system.properties" })
public class PropertiesConfig {

   @Autowired
   private Environment env;

   private static Environment environment;

   @PostConstruct
   public void init(){
     environment = env;
     System.out.println(environment == env);
   }

   public static String getPopertyValue(String property){
      return environment.getProperty(property);
   }
}
Share:
10,086
Shailesh Vaishampayan
Author by

Shailesh Vaishampayan

I am an experienced Java developer with almost 6+ years of experience in Java Web application development. I am an oen source technology enthusiast and like to explore and implement open source Java based technologies in my day to day work.

Updated on June 04, 2022

Comments

  • Shailesh Vaishampayan
    Shailesh Vaishampayan almost 2 years

    I am trying to use Environment abstraction & @PropertySource of Spring to load and use properties in my @Configuration annotated classes. However I get Environment as null in my PropertyConfig class as it is accessed from another @Configuration class PersistenceConfig which used it to access the properties. Here is my relevant code :

       @Configuration
      @PropertySource({ "classpath:/properties/email_${environment}.properties" })
      @PropertySource({ "classpath:/properties/appconfig.properties" })
      @PropertySource({ "classpath:/properties/ApplicationResources.properties" })
      @PropertySource({ "classpath:/properties/Database_${environment}.properties" })
      @PropertySource({ "classpath:/properties/log4j.properties" })
      @PropertySource({ "classpath:/properties/system.properties" })
      public class PropertiesConfig {
    
            @Autowired
            private Environment env;
    
            private static final PropertiesAccessor propertyAccessor = new                   PropertiesConfig().new PropertiesAccessor();
    
            public static String getPopertyValue(String property){
                return propertyAccessor.getPropertyValue(property);
            }
    
            private class PropertiesAccessor{
    
            public String getPropertyValue(String key){
                 return env.getProperty(key);
            }
        }
     }
    

    My Other @Configuration annotated class PersistenceConfig is as follows :

      @Configuration
      @EnableTransactionManagement
      @ComponentScan(basePackages = {"com.template"})
      public class PersistenceConfig {
    
             @Bean
             public LocalSessionFactoryBean sessionFactory(){
    
                    LocalSessionFactoryBean sessionFactory = new           LocalSessionFactoryBean();
                sessionFactory.setDataSource(dataSource());
                sessionFactory.setPackagesToScan(new String []                      {"com.template.domain" });
                sessionFactory.setHibernateProperties(hibernateProperties());
                return sessionFactory;
    
    
          }
    
         @Bean
         public BasicDataSource dataSource(){
    
                BasicDataSource dataSource = new BasicDataSource();
                           dataSource.setDriverClassName(PropertiesConfig.getPopertyValue("jdbc.driverClassName"));
                dataSource.setUrl(PropertiesConfig.getPopertyValue("jdbc.url"));
                  dataSource.setUsername(PropertiesConfig.getPopertyValue("jdbc.user"));
                         dataSource.setPassword(PropertiesConfig.getPopertyValue("jdbc.pass"));
    
                return dataSource;
     }
    
    
     @Bean
     public HibernateTransactionManager transactionManager(){
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory().getObject());
        return transactionManager;
    }
    
    Properties hibernateProperties(){
          return new Properties() {
              {
                 setProperty("hibernate.hbm2ddl.auto", PropertiesConfig.getPopertyValue("hibernate.hbm2ddl.auto"));
                 setProperty("hibernate.dialect", PropertiesConfig.getPopertyValue("hibernate.dialect"));
                 setProperty("hibernate.globally_quoted_identifiers", "true");
              }
           };
    
    }
    

    }

    However I get NullpointerException when dataSource() method of PersistenceConfig tries to retrieve properties using PropertiesConfig.getPopertyValue("jdbc.driverClassName") because env of type Environment is null in PropertyConfig.

    I am loading both classes as follows in my WebApplicationInitializer :

     public class WebAppInitializer implements WebApplicationInitializer {
    
    @Override
    public void onStartup(ServletContext container) {
        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(PropertiesConfig.class,SecurityConfig.class,PersistenceConfig.class,ApplicationConfig.class);
        //rootContext.register(ApplicationConfig.class, PersistenceConfig.class, SecurityConfig.class); I have not added security yet
    
        // Manage the life-cycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));
    
        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
        dispatcherServlet.register(MvcConfig.class);
    
        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    
    }
    

    }

    As far as I understand PersistenceConfig is being loaded first before PropertyConfig. Am I right? Or is there any other reason? How to make this work?