-
Mar 20th, 2013, 06:18 PM
#1
Late binding for multiple jobs
Hi,
I have 2 jobs def:
<job id="Company">
<step id="step1">
<tasklet>
<chunk reader="companyReader" writer="companyWriter"
processor="companyProcessor" commit-interval="2" />
</tasklet>
</step>
</job>
and
<job id="Person" xmlns="http://www.springframework.org/schema/batch">
<step id="step1">
<tasklet>
<chunk reader="personReader" writer="personWriter"
commit-interval="2" />
<listeners>
<listener ref="PersonReaderListener" />
</listeners>
</tasklet>
</step>
</job>
<bean id="personReader" class="org.springframework.batch.item.file.FlatFil eItemReader"
scope="step">
<property name="resource" value="#{jobParameters['inputFile']}" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping .DefaultLineMapper">
<property name="lineTokenizer" ref="personTokenizer" />
<property name="fieldSetMapper" ref="personFieldSetMapper" />
</bean>
</property>
</bean>
When I'm trying to run the "Company" job, it complains about:
2013-03-20 16:10:13,583 ERROR [org.springframework.batch.core.step.AbstractStep] - <Encountered an error executing the step>
org.springframework.batch.item.ItemStreamException : Failed to initialize the reader
at org.springframework.batch.item.support.AbstractIte mCountingItemStreamItemReader.open(AbstractItemCou ntingItemStreamItemReader.java:137)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at org.springframework.aop.support.AopUtils.invokeJoi npointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethod Invocation.invokeJoinpoint(ReflectiveMethodInvocat ion.java:183)
at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :150)
at org.springframework.aop.support.DelegatingIntroduc tionInterceptor.doProceed(DelegatingIntroductionIn terceptor.java:131)
at org.springframework.aop.support.DelegatingIntroduc tionInterceptor.invoke(DelegatingIntroductionInter ceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :172)
at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy11.open(Unknown Source)
at org.springframework.batch.item.support.CompositeIt emStream.open(CompositeItemStream.java:93)
at org.springframework.batch.core.step.tasklet.Taskle tStep.open(TaskletStep.java:301)
at org.springframework.batch.core.step.AbstractStep.e xecute(AbstractStep.java:192)
at org.springframework.batch.core.job.SimpleStepHandl er.handleStep(SimpleStepHandler.java:135)
at org.springframework.batch.core.job.flow.JobFlowExe cutor.executeStep(JobFlowExecutor.java:61)
at org.springframework.batch.core.job.flow.support.st ate.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.Si mpleFlow.resume(SimpleFlow.java:144)
at org.springframework.batch.core.job.flow.support.Si mpleFlow.start(SimpleFlow.java:124)
at org.springframework.batch.core.job.flow.FlowJob.do Execute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.exe cute(AbstractJob.java:293)
at org.springframework.batch.core.launch.support.Simp leJobLauncher$1.run(SimpleJobLauncher.java:120)
at org.springframework.core.task.SyncTaskExecutor.exe cute(SyncTaskExecutor.java:48)
at org.springframework.batch.core.launch.support.Simp leJobLauncher.run(SimpleJobLauncher.java:114)
Caused by:
java.lang.IllegalStateException: Input resource must exist (reader is in 'strict' mode): class path resource [aaa.txt]
at org.springframework.batch.item.file.FlatFileItemRe ader.doOpen(FlatFileItemReader.java:250)
at org.springframework.batch.item.support.AbstractIte mCountingItemStreamItemReader.open(AbstractItemCou ntingItemStreamItemReader.java:134)
... 28 more
Since I use scope="step" for the personReader, so I assume the 'inputFile' parameter is only required when running the "Person" job, right?
Anything wrong?
Thanks
Ma Ling
Last edited by tutufool; Apr 3rd, 2013 at 08:30 PM.
-
Mar 20th, 2013, 06:34 PM
#2
btw, I'm using spring 3.2.0 and spring batch 2.1.9
-
Mar 21st, 2013, 02:46 AM
#3
I got the root cause: the second job's step has same id as the first, so the step bean in second job override the first job.
OK, here comes questions:
1. Does the step id for different jobs has to be globally unique? If yes, why no validation error throws when context start up?
2. is the step id a must have property? Does it allow an anonymous step?
Thanks
Ma Ling
-
Mar 22nd, 2013, 12:21 AM
#4
Hey,
I would rather use a meaningful Step id's instead of Step1. It make sense to use Step1 only for examples but when it comes to actual code, its recommended to use the meaningful names or ids.
However your questions are valid and will wait for a Spring Expert/Admin to answer.
Thanks,
Triguna
Learning spring-batch
-
Mar 27th, 2013, 02:19 AM
#5
i don't think it is valid reason, for above said Problem. whenever you inititalize spring bean factory , it will initialize each and every bean ,whether we are going to use it or not that is different issue, so if both job defines in single file , it will always throw error untill and unless u did not resolve root cause of error which is , file resource was not passed as part of job parameter ,
best solution is to move reader's resource value from job parameter context to step execution context and handle it manually to transfer job parameter to step execution in beforesteplistener and have a late binding.
-
Mar 29th, 2013, 01:55 PM
#6
While bmaduskar is correct in most cases, when defining a bean with the scope step, we provide a proxy to allow for deferred resolution of things like input/output files. I don't see the configuration for the companyReader bean. The exception you have simply states that when it tries to open the reader, the file isn't there. Why do you think it's the personReader that is causing the exception?
-
Apr 3rd, 2013, 08:29 PM
#7
I may paste the wrong log, the log should be:
2013-04-03 17:51:45,613 ERROR - Encountered an error executing the step
org.springframework.batch.item.ItemStreamException : Failed to initialize the reader
at org.springframework.batch.item.support.AbstractIte mCountingItemStreamItemReader.open(AbstractItemCou ntingItemStreamItemReader.java:137)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at org.springframework.aop.support.AopUtils.invokeJoi npointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethod Invocation.invokeJoinpoint(ReflectiveMethodInvocat ion.java:183)
at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :150)
at org.springframework.aop.support.DelegatingIntroduc tionInterceptor.doProceed(DelegatingIntroductionIn terceptor.java:131)
at org.springframework.aop.support.DelegatingIntroduc tionInterceptor.invoke(DelegatingIntroductionInter ceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :172)
at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy11.open(Unknown Source)
at org.springframework.batch.item.support.CompositeIt emStream.open(CompositeItemStream.java:93)
at org.springframework.batch.core.step.tasklet.Taskle tStep.open(TaskletStep.java:301)
at org.springframework.batch.core.step.AbstractStep.e xecute(AbstractStep.java:192)
at org.springframework.batch.core.job.SimpleStepHandl er.handleStep(SimpleStepHandler.java:135)
at org.springframework.batch.core.job.flow.JobFlowExe cutor.executeStep(JobFlowExecutor.java:61)
at org.springframework.batch.core.job.flow.support.st ate.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.Si mpleFlow.resume(SimpleFlow.java:144)
at org.springframework.batch.core.job.flow.support.Si mpleFlow.start(SimpleFlow.java:124)
at org.springframework.batch.core.job.flow.FlowJob.do Execute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.exe cute(AbstractJob.java:293)
at org.springframework.batch.core.launch.support.Simp leJobLauncher$1.run(SimpleJobLauncher.java:120)
at org.springframework.core.task.SyncTaskExecutor.exe cute(SyncTaskExecutor.java:48)
at org.springframework.batch.core.launch.support.Simp leJobLauncher.run(SimpleJobLauncher.java:114)
at org.springframework.batch.core.launch.support.Comm andLineJobRunner.start(CommandLineJobRunner.java:3 49)
at org.springframework.batch.core.launch.support.Comm andLineJobRunner.main(CommandLineJobRunner.java:57 4)
Caused by: java.lang.IllegalArgumentException: Input resource must be set
at java.lang.Throwable.<init>(Throwable.java:67)
at org.springframework.util.Assert.notNull(Assert.jav a:111)
at org.springframework.batch.item.file.FlatFileItemRe ader.doOpen(FlatFileItemReader.java:244)
at org.springframework.batch.item.support.AbstractIte mCountingItemStreamItemReader.open(AbstractItemCou ntingItemStreamItemReader.java:134)
... 28 more
It's a job run for "Company", so personReader should not be initialized, right?
That's why I'm guessing Person job's step1 override Company job's step1.
questions:
1. in 1 xml definition, if there's 2 jobs with same Id, will batch framework throw exception?
2. in 1 xml definiiton, if 2 steps have same id, but they belong to different job, will framework throw exception?
3. for above #2, if not exception threw, will override happen just like my case?
samples:
<job id="job1" ...
<step id="step1"...
<job id="job2"...
<step id="step1"...
Thanks
Ma Ling
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules