0

(First time posting a question on this forum, so please ignore any silly stuff) Working on fresh Spring Boot oriented project which has multiple configuration classes (Security, DataSourceConfig, DataConfig). The issue is DataConfig is using some bean defined in DataSourceConfig, but since the DataConfig is loading first, it is not getting that dependency.

@Configuration
public class DataSourceConfig {

    @Bean(name="abcDataSource")
    public DataSource abcDataSource() {
        final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
        dsLookup.setResourceRef(true);
        DataSource dataSource = dsLookup.getDataSource("java:comp/env/jdbc/ABC");
        return dataSource;
    }

    @Bean(name="xyzDataSource")
    @Lazy
    public DataSource xyzDataSource() {
        final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
        dsLookup.setResourceRef(true);
        DataSource dataSource = dsLookup.getDataSource("java:comp/env/jdbc/XYZ");
        return dataSource;
    }
}

@Import({DataSourceConfig.class})
@Configuration
public class DataConfig {

    @Autowired 
    DataSource xyzDataSource;

    @Bean
    public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() throws Exception {
        PropertyPlaceholderConfigurer p = new PropertyPlaceholderConfigurer();
        p.setProperties(commonsConfigurationFactoryBean());
        return p;
    }

    @Bean
    public Properties commonsConfigurationFactoryBean() {
        return ConfigurationConverter.getProperties(databaseConfiguration());
    }

    @Bean
    @Autowired
    public DatabaseConfiguration databaseConfiguration() {
        return new DatabaseConfiguration(xyzDataSource, "Table_Name", "Key_Column", "Value_Column");

    }
}

So when I am starting the TOMCAT server (which is not the embedded one) in DEBUG mode having breakpoints on DataConfig.databaseConfiguration() and DataSourceConfig.xyzDataSource(), it always goes to former one instead of later, which is causing issues and giving "NullPointerException" for not getting datasource.

I don't know why '@Import' is not working for this. Any help would be really appriciated. Please let me know if you need any other info from my end.

Exception Trace:

Caused by: java.lang.NullPointerException
    at org.apache.commons.configuration.DatabaseConfiguration.getConnection(DatabaseConfiguration.java:568) ~[commons-configuration-1.6.jar:1.6]
    at org.apache.commons.configuration.DatabaseConfiguration.getKeys(DatabaseConfiguration.java:515) ~[commons-configuration-1.6.jar:1.6]
    at org.apache.commons.configuration.ConfigurationConverter.getProperties(ConfigurationConverter.java:112) ~[commons-configuration-1.6.jar:1.6]
    at com.mcmcg.apollo.common.datasource.DataConfig.commonsConfigurationFactoryBean(DataConfig.java:35) ~[classes/:?]
    at com.mcmcg.apollo.common.datasource.DataConfig$$EnhancerBySpringCGLIB$$bb4c1776.CGLIB$commonsConfigurationFactoryBean$1(<generated>) ~[classes/:?]
    at com.mcmcg.apollo.common.datasource.DataConfig$$EnhancerBySpringCGLIB$$bb4c1776$$FastClassBySpringCGLIB$$40819bbc.invoke(<generated>) ~[classes/:?]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356) ~[spring-context-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at com.mcmcg.apollo.common.datasource.DataConfig$$EnhancerBySpringCGLIB$$bb4c1776.commonsConfigurationFactoryBean(<generated>) ~[classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_73]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_73]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_73]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_73]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1128) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1023) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:381) ~[spring-context-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at com.mcmcg.apollo.common.datasource.DataConfig$$EnhancerBySpringCGLIB$$bb4c1776.commonsConfigurationFactoryBean(<generated>) ~[classes/:?]
    at com.mcmcg.apollo.common.datasource.DataConfig.propertyPlaceholderConfigurer(DataConfig.java:29) ~[classes/:?]
    at com.mcmcg.apollo.common.datasource.DataConfig$$EnhancerBySpringCGLIB$$bb4c1776.CGLIB$propertyPlaceholderConfigurer$0(<generated>) ~[classes/:?]
    at com.mcmcg.apollo.common.datasource.DataConfig$$EnhancerBySpringCGLIB$$bb4c1776$$FastClassBySpringCGLIB$$40819bbc.invoke(<generated>) ~[classes/:?]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356) ~[spring-context-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at com.mcmcg.apollo.common.datasource.DataConfig$$EnhancerBySpringCGLIB$$bb4c1776.propertyPlaceholderConfigurer(<generated>) ~[classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_73]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_73]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_73]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_73]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    ... 27 more
Paul
  • 19,704
  • 14
  • 78
  • 96
Ankit A.
  • 11
  • 1
  • 3
  • 1
    You didn't show any code where `DataConfig` is actually trying to *use* that dependency. Spring is smart enough to wire it before invoking `@PostConstruct` or any `@Bean` methods. (Also, looks like you could deduplicate your `dsLookup` declaration, and the method name is the default bean name, so you don't need to specify that in the annotation.) – chrylis -cautiouslyoptimistic- Mar 23 '17 at 18:55
  • Please add the stack trace or the log – reos Mar 23 '17 at 19:32
  • Thanks for the response @chrylis. Its shown in DataConfig.databaseConfiguration() method where you can see 'xyzDataSource' is being passed as first constructor argument – Ankit A. Mar 23 '17 at 20:21
  • @reos, added the stack trace to my original question. – Ankit A. Mar 23 '17 at 20:26
  • You didn't show the code where the exception is being thrown. – chrylis -cautiouslyoptimistic- Mar 23 '17 at 20:29
  • @chrylis, I am not sure why you are not able to see that in the code of DataConfig class which I already have shared but still the line that throwing the exception is `return new DatabaseConfiguration(xyzDataSource, "Table_Name", "Key_Column", "Value_Column");` – Ankit A. Mar 23 '17 at 20:50
  • Hmmm There is something missing. Probably is the property holder. – reos Mar 23 '17 at 21:02
  • @reos, when I place all the bean in single configuration file, it works fine. – Ankit A. Mar 23 '17 at 21:17
  • Got a good understanding of what went wrong from: http://stackoverflow.com/questions/24643426/java-config-bean-not-autowired-in-other-configuration-class – Ankit A. Mar 23 '17 at 21:58
  • It looks like your code fell off the end of the formatting; please check. Note that using `@Autowired` on an `@Bean` method is meaningless, and it's generally better to make dependencies like this *method parameters* instead of fields. – chrylis -cautiouslyoptimistic- Mar 24 '17 at 15:30

0 Answers0