Reputation: 355
i'm using Spring batch to run (reading from database table and writing into another table) job
the job is scheduled by Quartz and the database is oracle and it's c3p0, i'm getting reader not open exception
this is the job context
<batch:job id="readyReqPoolJob">
<batch:step id="readyReqPoolStep">
<batch:tasklet>
<batch:chunk reader="readyReqPoolReader" writer="readyReqPoolWrtiter"
commit-interval="1000" />
</batch:tasklet>
</batch:step>
</batch:job>
<!-- ======================================================= -->
<!-- 6) READER -->
<!-- ======================================================= -->
<bean id="readyReqPoolReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="sql" value="select * from SF_ILA_Ready_Request_Pool" />
<property name="rowMapper" ref="ReadyReqPoolRowMapper" />
</bean>
<bean id="readyReqPoolWrtiter"
class="com.mobily.housekeepingservice.readyrequestpoolarchive.ReadyReqPoolArchiveWriter" />
<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass"
value="org.springframework.batch.sample.quartz.JobLauncherDetails" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="readyReqPoolJob" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="jobDetail" />
<property name="cronExpression" value="0 0/5 * * * ?" />
</bean>
</property>
</bean>
the main context is:
<import resource="classpath:spring/batch/config/readyReqPoolContext.xml" />
<import resource="classpath:spring/batch/config/jdbc.commons.xml" />
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean
class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
<bean id="jobRegistry"
class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>
<!-- 4) LAUNCH JOBS FROM A REPOSITORY -->
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
<property name="taskExecutor" ref="taskExecutor" />
</bean>
<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
the exception is:
09:59:20,108 INFO ClassPathXmlApplicationContext:510 - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@99436c6: startup date [Sun Mar 02 09:59:20 AST 2014]; root of context hierarchy
09:59:20,159 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [spring/batch/config/mainContext.xml]
09:59:20,285 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [spring/batch/config/readyReqPoolContext.xml]
09:59:20,379 INFO DefaultListableBeanFactory:663 - Overriding bean definition for bean 'readyReqPoolJob': 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.JobPars
erJobFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
09:59:20,383 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [spring/batch/config/jdbc.commons.xml]
09:59:20,744 INFO ClassPathXmlApplicationContext:1374 - Bean 'jobRegistry' of type [class org.springframework.batch.core.configuration.support.MapJobRegistry] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible
for auto-proxying)
09:59:20,759 INFO ClassPathXmlApplicationContext:1374 - Bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0' of type [class org.springframework.transaction.annotation.AnnotationTransactionAttributeSource] is not e
ligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
09:59:20,761 INFO ClassPathXmlApplicationContext:1374 - Bean 'org.springframework.transaction.config.internalTransactionAdvisor' of type [class org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor] is not eligible
for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
09:59:20,778 INFO DefaultListableBeanFactory:596 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@53ddc692: defining beans [org.springframework.batch.core.scope.internalStepScope,org.springframew
ork.beans.factory.config.CustomEditorConfigurer,org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor,readyReqPoolStep,readyReqPoolJob,readyReqPoolReader,readyReqPoolWrtiter,jobDetail,org.springframework.scheduling.quartz.Schedu
lerFactoryBean#0,dataSource,appJobExecutionListener,exceptionLogArchiveDAOImp,ExceptionLogRowMapper,exceptionLogWriter,itemFailureLoggerListener,log4jDebugArchiveDAOImp,log4jDebugArchiveWriter,Log4jDebugRowMapper,log4jErrorArchiveDAOImp,log4jErrorArc
hiveWriter,Log4jErrorRowMapper,log4jFatalArchiveDAOImp,log4jFatalArchiveWriter,Log4jFatalRowMapper,log4jInfoArchiveDAOImp,log4jInfoArchiveWriter,Log4jInfoRowMapper,log4jTraceArchiveDAOImp,log4jTraceArchiveWriter,Log4jTraceRowMapper,log4jWarnArchiveDA
OImp,log4jWarnArchiveWriter,Log4jWarnRowMapper,readyReqPoolArchiveDAOImp,readyReqPoolArchiveWriter,ReadyReqPoolRowMapper,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAu
towiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,
org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,jdbcTemplate,org.springframework.
batch.core.configuration.support.JobRegistryBeanPostProcessor#0,jobRegistry,jobRepository,jobLauncher,taskExecutor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
09:59:20,812 INFO MLog:80 - MLog clients using log4j logging.
09:59:20,911 INFO C3P0Registry:204 - Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
09:59:21.296 [main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
09:59:21.312 [main] INFO o.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
09:59:21.314 [main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.1.8.6 created.
09:59:21.315 [main] INFO org.quartz.simpl.RAMJobStore - RAMJobStore initialized.
09:59:21.315 [main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v1.8.6) 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
09:59:21.316 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' initialized from an externally provided properties instance.
09:59:21.316 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 1.8.6
09:59:21.317 [main] INFO org.quartz.core.QuartzScheduler - JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@1fe0d622
09:59:21,491 INFO DefaultLifecycleProcessor:334 - Starting beans in phase 2147483647
09:59:21,491 INFO SchedulerFactoryBean:648 - Starting Quartz Scheduler now
09:59:21.491 [main] INFO org.quartz.core.QuartzScheduler - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED started.
09:59:21,532 INFO AbstractPoolBackedDataSource:462 - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 1, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -
> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 2rzno590zyfq8arapgjr|2022d1f4, debugUnreturnedCon
nectionStackTraces -> false, description -> null, driverClass -> oracle.jdbc.driver.OracleDriver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 2rzno590zyfq8arapgjr|2022d1f4, idleConnectionTestPeriod -> 10
000, initialPoolSize -> 4, jdbcUrl -> jdbc:oracle:thin:@10.14.11.186:1522:EMADEV, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 12, maxStatements -> 0, maxStatementsPerConne
ction -> 0, minPoolSize -> 8, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> SELECT 1 FROM DUAL, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnect
ionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
Exit Status : STARTING
Done
09:59:22,170 INFO SimpleJobLauncher:132 - Job: [FlowJob: [name=readyReqPoolJob]] launched with the following parameters: [{time=1393743561493}]
09:59:22,272 INFO SimpleStepHandler:135 - Executing step: [readyReqPoolStep]
09:59:22.314 [Timer-0] DEBUG org.quartz.utils.UpdateChecker - Checking for available updated version of Quartz...
10:00:00.011 [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1] DEBUG org.quartz.core.JobRunShell - Calling execute on job DEFAULT.jobDetail
10:00:00,017 INFO JobLauncherDetails:69 - Quartz trigger firing with Spring Batch jobName=readyReqPoolJob
10:00:00,051 INFO SimpleJobLauncher:132 - Job: [FlowJob: [name=readyReqPoolJob]] launched with the following parameters: [{}]
10:00:00,104 INFO SimpleStepHandler:135 - Executing step: [readyReqPoolStep]
10:00:00,112 ERROR AbstractStep:222 - Encountered an error executing the step
org.springframework.batch.item.ItemStreamException: Failed to initialize the reader
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:142)
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:96)
at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:306)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:192)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:137)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:152)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:131)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:301)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:134)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.IllegalStateException: Stream is already initialized. Close before re-opening.
at org.springframework.util.Assert.state(Assert.java:385)
at org.springframework.batch.item.database.AbstractCursorItemReader.doOpen(AbstractCursorItemReader.java:399)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:139)
... 12 more
10:00:00,145 INFO SimpleJobLauncher:135 - Job: [FlowJob: [name=readyReqPoolJob]] completed with the following parameters: [{}] and the following status: [FAILED]
10:00:04,963 ERROR AbstractStep:222 - Encountered an error executing the step
org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read.
at org.springframework.batch.item.database.AbstractCursorItemReader.doRead(AbstractCursorItemReader.java:440)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:83)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:91)
at org.springframework.batch.core.step.item.SimpleChunkProvider.read(SimpleChunkProvider.java:155)
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:114)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:108)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:395)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:267)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:253)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:137)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:152)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:131)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:301)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:134)
at java.lang.Thread.run(Thread.java:744)
10:00:04,999 INFO SimpleJobLauncher:135 - Job: [FlowJob: [name=readyReqPoolJob]] completed with the following parameters: [{time=1393743561493}] and the following status: [FAILED]
Upvotes: 4
Views: 10300
Reputation: 21503
The issue here is that your reader is singleton scoped. This means that when the job runs the first time, the ItemReader is opened successfully and the job runs. However when the job attempts to run a second time, it's using the same instance it did the first time which is already initialized (hence the exception). I'd recommend changing the readyReqPoolReader to be a step scoped bean and see if that helps.
You can read more about step scope here: http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/scope/StepScope.html
Upvotes: 5