I wrote an easy scheduler included in my Spring Application. I run my local server and after few seconds, in class Importer, checker.start() is being invoked each 5 seconds as how I configured in config file.
After that, this method invokes Job with JobLauncher and here I have got an error.
org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: A job instance already exists and is complete for p arameters={}. If you want to run this job again, change the parameters.
I found a solution how to fix it using annotation but I want to keep it this way.
Thank you in advance
public class Importer {
private Checker checker;
public Importer() {
}
public void myMethod() {
try {
checker.start();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
with .xml file:
<bean id="schedulerTask"
class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="fileimport" />
<property name="targetMethod" value="myMethod" />
</bean>
<bean id="fileimport" />
<property name="targetMethod" value" class="com...Importer">
<property name="checker">
<bean id="checker" class="com...Checker">
</bean>
</property>
</bean>
<bean id="scheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask" ref="schedulerTask" />
<property name="delay" value="${xyz.startdelay}" />
<property name="period" value="${xyz.checkinterval}" />
</bean>
<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref local="scheduledTask" />
</list>
</property>
</bean>
And property file:
xyz.checkinterval=5000
xyz.startdelay=0
In class Checker I have got the method:
static ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("/simplefile-context.xml");
Job job = (Job) applicationContext.getBean("fileBatch");
JobLauncher launcher = (JobLauncher) applicationContext.getBean("jobLauncher");
public void start() throws ClientProtocolException, IOException {
// ...
try {
launcher.run(job, new JobParameters());
} catch (Exception e) {
e.printStackTrace();
}
}
and my "simplefile-context.xml" file looks like this:
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
</bean>
<!-- bean for lauching the job -->
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<task:executor id="taskExecutor" pool-size="100" />
<!-- -->
<!-- JOBS -->
<!-- -->
<batch:job id="fileBatch" restartable="true">
<batch:step id="readLines" >
<batch:tasklet task-executor="taskExecutor" >
<batch:chunk reader="fileReader" writer="fooWriter" commit-interval="100" />
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="fileReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="linesToSkip" value="1"/>
<property name="resource" value="file:./src/main/resources/sample.csv" />
<property name="lineMapper" ref="lineMapper" />
</bean>
<bean id="lineMapper" class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer" ref="lineTokenizer"/>
<property name="fieldSetMapper" ref="fieldsetEntityMapper"/>
</bean>
<bean id="lineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value=";" />
<property name="names" value="field1,field2,field3,field4,field5,field6,field7" />
<property name="strict" value="false"/>
</bean>
<bean id="fieldsetEntityMapper" class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="targetType" value="com...model.ModelObject"/>
<property name="customEditors">
<map>
<entry key="java.lang.Double">
<bean class="org.springframework.beans.propertyeditors.CustomNumberEditor">
<constructor-arg index="0" value="java.lang.Double"/>
<constructor-arg index="1" value="true"/>
</bean>
</entry>
</map>
</property>
</bean>
<bean id="fooWriter" class="com...springbatch.writer.FooWriter" />
With your current setup you will only be able to launch the job only once.
The job is unique identified by its
idtogether with the parameters. Currently there is no way to make a distinction based on the parameters. Instead of addingnew JobParameters()use theJobParamtersBuilderBuilderand add the current date and time.This will allow you to run the job multiple times.