title: Spring Batch Creating Customized reader by extending JdbcCursorItemReader
body: <p>I need to make a customized reader by extending JdbcCursorItemReader. I am doing it as below:</p>
  
  <pre><code>package sample.peektry;
  
  import org.springframework.batch.item.ItemReader;
  import org.springframework.batch.item.NonTransientResourceException;
  import org.springframework.batch.item.ParseException;
  import org.springframework.batch.item.UnexpectedInputException;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Component;
  
  @Component("myReader")
  public class MyReader implements ItemReader&lt;MyBean&gt; {
  
      @Autowired
      MyPeekableReader myPeekableReader;
  
      public MyPeekableReader getMyPeekableReader() {
          return myPeekableReader;
      }
  
      public void setMyPeekableReader(MyPeekableReader myPeekableReader) {
          this.myPeekableReader = myPeekableReader;
      }
  
      @Override
      public MyBean read() throws Exception, UnexpectedInputException,
      ParseException, NonTransientResourceException {
          System.out.println(" I will peek and read... :)");
          return null;
      }
  
  }
  
  package sample.peektry;
  
  import org.springframework.batch.item.support.SingleItemPeekableItemReader;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Component;
  
  @Component("myPeekableReader")
  public class MyPeekableReader extends SingleItemPeekableItemReader&lt;MyBean&gt; {
  
      @Autowired
      private MyJdbcReader myJdbcReader;
  
      public MyJdbcReader getMyJdbcReader() {
          return myJdbcReader;
      }
  
      public void setMyJdbcReader(MyJdbcReader myJdbcReader) {
          this.myJdbcReader = myJdbcReader;
      }
  
  
  }
  </code></pre>
  
  <p>Further, <code>MyRowMapper implements RowMapper</code> and has <code>@Component("myRowMapper")</code>. Similarly, <code>MyPrepStmntSetter implements PreparedStatementSetter</code> and has <code>@Component("myPrepStmntSetter")</code></p>
  
  <pre><code>package sample.peektry;
  
  import javax.annotation.Resource;
  import javax.sql.DataSource;
  import org.springframework.batch.item.database.JdbcCursorItemReader;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Component;
  
  @Component("myJdbcReader")
  public class MyJdbcReader extends JdbcCursorItemReader&lt;MyBean&gt; {
  
      @Resource
      DataSource dataSource;
  
      @Autowired
      MyRowMapper myRowMapper;
  
      @Autowired
      MyPrepSetter myPrepSetter;
  
      public DataSource getDataSource() {
          return dataSource;
      }
  
      public void setDataSource(DataSource dataSource) {
          this.dataSource = dataSource;
      }
  
      public MyRowMapper getMyRowMapper() {
          return myRowMapper;
      }
  
      public void setMyRowMapper(MyRowMapper myRowMapper) {
          this.myRowMapper = myRowMapper;
      }
  
      public MyPrepSetter getMyPrepSetter() {
          return myPrepSetter;
      }
  
      public void setMyPrepSetter(MyPrepSetter myPrepSetter) {
          this.myPrepSetter = myPrepSetter;
      }
  
  
  
  
  }
  </code></pre>
  
  <p>Configurations:</p>
  
  <ol>
  <li><p>in batch-infra.xml:</p>
  
  <pre><code>&lt;batch:job-repository id="jobRepository" data-source="dataSource"
                    transaction-manager="transactionManager" /&gt;
  
  &lt;!-- connect to database --&gt;
  &lt;bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
      &lt;property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver" /&gt;
      &lt;property name="url" value="jdbc:derby://localhost:1527/MyDB" /&gt;
  </code></pre>
  
  <p></p>
  
  <pre><code>&lt;bean id="jobLauncher"
        class="org.springframework.batch.core.launch.support.SimpleJobLauncher"&gt;
      &lt;property name="jobRepository" ref="jobRepository"&gt;&lt;/property&gt;
  </code></pre>
  
  <p></p>
  
  <pre><code>&lt;bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
      &lt;property name="dataSource" ref="dataSource"&gt;&lt;/property&gt;
  </code></pre>
  
  <p></p></li>
  <li><p>batch-jobs.xml:</p>
  
  <pre><code>&lt;import resource="classpath:/META-INF/spring/batch/jobs/myJob.xml" /&gt;
  </code></pre></li>
  <li><p>in app-context.xml(after xmlns and all):</p>
  
  <pre><code>&lt;context:component-scan base-package="sample.peektry" /&gt;
  
  &lt;import resource="classpath:/META-INF/spring/batch/batch-infra.xml" /&gt;
  
  &lt;import resource="classpath:/META-INF/spring/batch/batch-jobs.xml" /&gt;
  </code></pre></li>
  </ol>
  
  <p>The above configuration is working fine for all the properties except dataSource. I.e. on running, I am getting: <code>IllegalArgumentException DataSource must be provided</code></p>
  
  <p><strong>Stacktrace:</strong></p>
  
  <pre><code>2014-02-16 14:56:07,195 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - &lt;Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@c7e553: startup date [Sun Feb 16 14:56:07 IST 2014]; root of context hierarchy&gt;
  2014-02-16 14:56:07,291 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - &lt;Loading XML bean definitions from class path resource [META-INF/spring/app-context.xml]&gt;
  2014-02-16 14:56:07,625 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - &lt;Loading XML bean definitions from class path resource [META-INF/spring/batch/batch-infra.xml]&gt;
  2014-02-16 14:56:10,210 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - &lt;Loading XML bean definitions from class path resource [META-INF/spring/batch/batch-jobs.xml]&gt;
  2014-02-16 14:56:12,766 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - &lt;Loading XML bean definitions from class path resource [META-INF/spring/batch/jobs/myJob.xml]&gt;
  2014-02-16 14:56:12,872 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - &lt;Overriding bean definition for bean 'myJob': replacing [Generic bean: class [org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.springframework.batch.core.configuration.xml.JobParserJobFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]&gt;
  2014-02-16 14:56:13,115 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - &lt;Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1d332b: defining beans [myJdbcReader,myPeekableReader,myPrepSetter,myReader,myRowMapper,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.batch.core.scope.internalStepScope,org.springframework.beans.factory.config.CustomEditorConfigurer,org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor,jobRepository,dataSource,jobLauncher,transactionManager,step1,myJob]; root of factory hierarchy&gt;
  2014-02-16 14:56:13,215 INFO [org.springframework.jdbc.datasource.DriverManagerDataSource] - &lt;Loaded JDBC driver: org.apache.derby.jdbc.ClientDriver&gt;
  2014-02-16 14:56:13,304 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - &lt;Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1d332b: defining beans [myJdbcReader,myPeekableReader,myPrepSetter,myReader,myRowMapper,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.batch.core.scope.internalStepScope,org.springframework.beans.factory.config.CustomEditorConfigurer,org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor,jobRepository,dataSource,jobLauncher,transactionManager,step1,myJob]; root of factory hierarchy&gt;
  Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myJdbcReader' defined in file [C:\Users\user\Documents\workspace-sts-3.3.0.RELEASE\sb-listener-test\target\classes\sample\peektry\MyJdbcReader.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: DataSource must be provided
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
      at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
      at org.springframework.context.support.ClassPathXmlApplicationContext.&lt;init&gt;(ClassPathXmlApplicationContext.java:139)
      at org.springframework.context.support.ClassPathXmlApplicationContext.&lt;init&gt;(ClassPathXmlApplicationContext.java:83)
      at sample.peektry.MyMain.main(MyMain.java:16)
  Caused by: java.lang.IllegalArgumentException: DataSource must be provided
      at org.springframework.util.Assert.notNull(Assert.java:112)
      at org.springframework.batch.item.database.AbstractCursorItemReader.afterPropertiesSet(AbstractCursorItemReader.java:150)
      at org.springframework.batch.item.database.JdbcCursorItemReader.afterPropertiesSet(JdbcCursorItemReader.java:107)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
      ... 12 more
  </code></pre>
  
  <p>Where I am getting wrong? Is it due to mixing XML configuration and component scan?</p>