I've seen similar questions and tried many variants, came up with what should work but still having a NullPointerException. This is a web application, here's my AppListener's contextInitialized():
AnnotationConfigWebApplicationContext wac = new AnnotationConfigWebApplicationContext();
wac.setServletContext(sc);
wac.setParent(rootContext);
propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setLocation(new PathResource(_configFile)); // yes it's dynamic
wac.addBeanFactoryPostProcessor(propertySourcesPlaceholderConfigurer);
wac.register(Configuration.class);
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
//TODO check if works properly - security. didn't manage to keep it in the same config class
wac.register(SecurityConfiguration.class);
wac.refresh();
here's my config class (Configuration.class):
@Autowired //(used to be @Inject, no difference)
private Environment env;
@Bean
public MessageSource messageSource(){
ReloadableResourceBundleMessageSource ms = new ReloadableResourceBundleMessageSource();
ms.addBasenames(new String[]{
env.getProperty("paths.appConfigDir") + "/i18n/message",
env.getProperty("paths.defaultConfigDir") + "/i18n/message"
});
ms.setDefaultEncoding("UTF-8");
return ms;
}
env is null, thus NPE.
What am I doing wrong?
What is a modern way to do have properties from a file loaded both into placeholders and environment, having properties file name evaluated at startup (basically, taken from another config file)?
What order should be my app context mehtods calls? (Guessing here's my mistake)
Add Let me additionally stress that the properties file name is a variable
Update The correct answer is marked below: don't do weird things or you'll face some gotchas.
Though the answer and the advice is correct, it didn't help me due to other reasons that me as an unexperienced Spring user had no idea that were worth included to the question. Basically, I've got an answer to my question, but I couldn't follow the advice, had to deep debug things and found out the following two items you may consider if you followed my route:
The config class was instantiated too early and thus lacked the Environment injected, because:
1) Don't call your configuration class "Configuration". During the initialization phase Something in Spring Web tries to get the bean called "configuration", sees this class and instantiates it.
2) Move messageSource bean to a parent context, as it is sought early in Spring Web initialization; it seems impossible to query the Environment in the messageSource bean method, there's no Environment yet.
Hope this helps.