Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Framework IllegalArgumentException 'dataSource' or 'jdbcTemplate' is required JAVA

I am trying to write spring application which is annotation configured. I have defined a dataSource and jdbcTemplate and i am sure that spring initializes them (when commented them i have an exception which tells me that this beans are not initialized). I have no idea why i have this exception when beans are initialize. I will copy xml, dao class and stacktrace.

xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql://localhost:5432/test" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg>
            <ref bean="dataSource" />
        </constructor-arg>
    </bean>

</beans> 

dao

@Repository
public class DomainsDao extends JdbcDaoSupport {

    @Autowired
    private MessageSourceAccessor msa;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public List<Domain> getInactiveDomains() {
        return jdbcTemplate.query(msa.getMessage("sql.pass.domain.select_inactive"), new DomainRowMapper());
    }
public int getDomainId(String name) {
        String sql = msa.getMessage("sql.pass.domain.select_by_name");
        Object[] args = new Object[] { name };
        return jdbcTemplate.queryForObject(sql, args, Integer.class);
    }
}

stack trace

java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate' is required
    org.springframework.jdbc.core.support.JdbcDaoSupport.checkDaoConfig(JdbcDaoSupport.java:111)
    org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1631)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1208)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1208)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:667)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:633)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:681)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:552)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:493)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    javax.servlet.GenericServlet.init(GenericServlet.java:158)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)

EDIT i will add all of my configuration

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <description>
    SaaS Admin
  </description>

    <display-name>SaaS Admin</display-name>

    <!-- <error-page> <error-code>404</error-code> <location>/error404.jsp</location> 
        </error-page> -->

    <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/conf/app-config.xml
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

app-config.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    <!-- Scanning package with configuration files -->

    <context:component-scan base-package="bg.abv.saas.admin.config" />

    <!-- Application Message Bundle -->

    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>WEB-INF/props/configure</value>
                <value>WEB-INF/props/sql</value>
                <value>WEB-INF/props/strings</value>
                <value>WEB-INF/props/log4j</value>
            </list>
        </property>
        <property name="defaultEncoding" value="UTF-8" />
        <property name="cacheSeconds" value="60" />
    </bean>

    <bean id="msa"
        class="org.springframework.context.support.MessageSourceAccessor">
        <constructor-arg>
            <ref bean="messageSource" />
        </constructor-arg>
    </bean>

WebServletApplicationInitializer

@EnableWebMvc
@Configuration
@ComponentScan("bg.abv")
@ImportResource(value = { "/WEB-INF/conf/data-source.xml" })
public class WebServletApplicationInitializer extends WebMvcConfigurerAdapter {

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/*");
    }

data-source.xml the content of this file is the xml file with dataSource and jdbcTemplate beans.

like image 625
RockOrDead Avatar asked Mar 17 '16 12:03

RockOrDead


2 Answers

I think you should drop the autowiring of jdbcTemplate in your DomainsDao and inject your dataSource instead. Then get the jdbcTemplate by calling the org.springframework.jdbc.core.support.JdbcDaoSupport#getJdbcTemplate method.

example:

@Repository
public class DomainsDao extends JdbcDaoSupport {

    @Autowired
    private MessageSourceAccessor msa;

    @Autowired
    public void setDs(DataSource dataSource) {
         setDataSource(dataSource);
    }

    public List<Domain> getInactiveDomains() {
        return getJdbcTemplate().query(msa.getMessage("sql.pass.domain.select_inactive"), new DomainRowMapper());
    }
    public int getDomainId(String name) {
        String sql = msa.getMessage("sql.pass.domain.select_by_name");
        Object[] args = new Object[] { name };
        return getJdbcTemplate().queryForObject(sql, args, Integer.class);
    }
}

If you still want to inject your own jdbcTemplate a similar approach is required:

@Repository
public class DomainsDao extends JdbcDaoSupport {

    @Autowired
    private MessageSourceAccessor msa;

    @Autowired
    public void setJT(JdbcTemplate jdbcTemplate) {
         setJdbcTemplate(jdbcTemplate);
    }

    public List<Domain> getInactiveDomains() {
        return getJdbcTemplate().query(msa.getMessage("sql.pass.domain.select_inactive"), new DomainRowMapper());
    }
    public int getDomainId(String name) {
        String sql = msa.getMessage("sql.pass.domain.select_by_name");
        Object[] args = new Object[] { name };
        return getJdbcTemplate().queryForObject(sql, args, Integer.class);
    }
}
like image 84
pleft Avatar answered Nov 14 '22 22:11

pleft


The problem is that the JdbcDaoSupport class that you are inheriting from already has a jdbcTemplate property that you need to set. The JdbcDaoSupport checks whether you have provided either the jdbcTemplate or dataSource property in its afterPropertiesSet method. However you are declaring and injecting your own jdbcTemplate meaning DomainsDao has two jdbcTemplate properties (one you declare plus one inherited from JdbcDaoSupport)

You can solve this by removing the extends JdbcDaoSupport part from your calss declaration.

Alternatively if you really want to inherit from JdbcDaoSupport then change your class as follows

@Repository
public class DomainsDao extends JdbcDaoSupport {

    @Autowired
    private MessageSourceAccessor msa;

    @Autowired
    public DomainsDao (JdbcTemplate jdbcTemplate){
       setJdbcTemplate(jdbcTemplate);
    }

    public List<Domain> getInactiveDomains() {
        return getJdbcTemplate().query(msa.getMessage("sql.pass.domain.select_inactive"), new DomainRowMapper());
    }
public int getDomainId(String name) {
        String sql = msa.getMessage("sql.pass.domain.select_by_name");
        Object[] args = new Object[] { name };
        return getJdbcTemplate.queryForObject(sql, args, Integer.class);
    }
}
like image 38
ekem chitsiga Avatar answered Nov 14 '22 22:11

ekem chitsiga