Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autowire Environment interface to spring social showcase example always return NULL

I am new to Spring and Spring social. I was trying to modify the existing spring social showcase example to change the data source to Apache Basic Data Source pointing to local MySQL database. However, when I autowire/inject Environment class to get the jdbc url from application.properties file, I always got null value

The AppConfig class is the same as the MainConfig on spring showcase GitHub except I added environment injection

@Configuration
@ComponentScan(basePackages = "org.springframework.social.showcase")
@PropertySource("classpath:org/springframework/social/showcase/config/application.properties")
@EnableTransactionManagement
public class AppConfig {

    @Autowired
    Environment environment;

    @Bean(destroyMethod = "shutdown")
    public DataSource dataSource() {
        environment.getProperty("jdbc.url");
....

I am sure the application.properties contains a property named "jdbc.url". The null pointer exception happened when spring application is starting. Below is the stacktrace:

Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource org.springframework.social.showcase.config.AppConfig.dataSource()] threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:181)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
    ... 60 more
Caused by: java.lang.NullPointerException
    at org.springframework.social.showcase.config.AppConfig.dataSource(AppConfig.java:55)
    at org.springframework.social.showcase.config.AppConfig$$EnhancerByCGLIB$$a0d39c08.CGLIB$dataSource$0(<generated>)
    at org.springframework.social.showcase.config.AppConfig$$EnhancerByCGLIB$$a0d39c08$$FastClassByCGLIB$$3d304ff8.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:286)
    at org.springframework.social.showcase.config.AppConfig$$EnhancerByCGLIB$$a0d39c08.dataSource(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
    ... 61 more

I am using Tomcat 7.0.40. The spring framework version is 3.2.2.release, same as the one in spring social showcase. Please let me know if you need further information to help me with this issue. Thanks a lot!!

For the next step, I am going to add JPA support to the spring social showcase example since spring data JPA provides many good features like the JPA repository. If someone can give me the guidance on this one, I will really appreciate that.

I already posted this question to http://forum.springsource.org/showthread.php?139141-Autowire-Environment-interface-to-spring-social-showcase-example-always-return-NULL!! You can take a look there if you need more details.

Thanks!

like image 934
ross the pooh Avatar asked Mar 24 '23 10:03

ross the pooh


1 Answers

Such "strange" behaviour usually happens when there are BeanFactoryPostProcessor in game. And indeed, the spring-social-sample contains a configuration bug, which is even being reported by Spring during its startup:

WARN : org.springframework.context.annotation.ConfigurationClassEnhancer - @Bean method MainConfig.propertyPlaceHolderConfigurer is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean Javadoc for complete details

Marking property placeholder factory method as static will fix it:

@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}
like image 150
Pavel Horal Avatar answered Apr 24 '23 18:04

Pavel Horal