How to Run two jobs simultaneously in spring batch

1.2k views Asked by At

I am trying to run two jobs irrespective with their scheduling time using Spring Batch and Spring Task Scheduler. Both the jobs(Tasklets) are doing different jobs at different time interval.

Following is the springConfig.xml file:

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

 http://www.springframework.org/schema/batch 
 http://www.springframework.org/schema/batch/spring-batch.xsd
 ">
 <context:component-scan
  base-package="com.mythribuswebservice.job,com.mythribuswebservice.job.scheduler" />
 <bean id="deleteOldOTPS" class="com.mythribuswebservice.job.tasklet.DeleteOldOTPWeekly"></bean>
 <bean id="couponToggleActivation"
  class="com.mythribuswebservice.job.tasklet.CouponToggleActivation"></bean>

 <batch:job id="otpJob" job-repository="jobRepository">
  <batch:step id="step1">
   <batch:tasklet ref="deleteOldOTPS">

   </batch:tasklet>
  </batch:step>
 </batch:job>
 <batch:job id="couponToggleActivation" job-repository="jobRepository">
  <batch:step id="couponActivation">
   <batch:tasklet ref="couponToggleActivation">

   </batch:tasklet>
  </batch:step>
 </batch:job>
 <bean id="jobRepository"
  class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
  <property name="transactionManager" ref="transactionManager" />
 </bean>
 <bean id="transactionManager"
  class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
 <bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://orcl/mythribus" />
  <property name="username" value="root" />
  <property name="password" value="root" />
 </bean>
 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  <property name="dataSource" ref="dataSource" />
 </bean>
 <bean id="jobLauncher"
  class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
  <property name="jobRepository" ref="jobRepository" />
 </bean>
 <bean id="oTPJobScheduler" class="com.mythribuswebservice.job.scheduler.OTPJobScheduler">
 </bean>
 <bean id="couponToggleActivationScheduler"
  class="com.mythribuswebservice.job.scheduler.CouponToggleActivationScheduler">
 </bean>
</beans>

Following are the implementation of CouponToggleActivationScheduler and OTPJobScheduler:

@EnableAsync

@EnableScheduling public class CouponToggleActivationScheduler {

@Autowired
JobLauncher jobLauncher;
@Autowired
Job couponToggleActivation;
final JobParametersBuilder jobParametersBuilder=new JobParametersBuilder();

@Scheduled(cron = "*/10 * * * * *")
public void runCouponActivationScheduler() {
    System.out.println("CouponToggleActivationScheduler" + new Date()+"-"+couponToggleActivation.hashCode());
    JobExecution execution;
    jobParametersBuilder.addString("couponToggleActivationScheduler", UUID.randomUUID().toString(), true);

        execution = jobLauncher.run(couponToggleActivation, jobParametersBuilder.toJobParameters());
        System.out.println("Exit Status : " + execution.getStatus());


}

}


public class OTPJobScheduler {

@Autowired
JobLauncher jobLauncher;
@Autowired
Job otpJob;
final JobParametersBuilder jobParametersBuilder=new JobParametersBuilder();


@Scheduled(cron = "*/10 * * * * *")
public void runOTPDeleteJob() {
    System.out.println("Ricks...." + new Date()+otpJob.hashCode());
    jobParametersBuilder.addString("otpJobScheduler", UUID.randomUUID().toString(),true);
    JobExecution execution;
        execution = jobLauncher.run(otpJob, jobParametersBuilder.toJobParameters());
        System.out.println("Exit Status : " + execution.getStatus());

}

}


There are Tasklets which do there respective work:

public class DeleteOldOTPWeekly implements Tasklet {}

public class CouponToggleActivation implements Tasklet {}

If i am running only one job the things work fine.but when i schedule the second too it gives exception:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponToggleActivation': Cannot create inner bean '(inner bean)#12e0f78' of type [org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean] while setting bean property 'flow'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#12e0f78': Cannot create inner bean '(inner bean)#693226' of type [org.springframework.batch.core.job.flow.support.StateTransition] while setting bean property 'stateTransitions' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#693226': Cannot create inner bean '(inner bean)#758545' of type [org.springframework.batch.core.job.flow.support.state.StepState] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#758545': Cannot resolve reference to bean 'couponActivation' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponActivation': Cannot resolve reference to bean 'couponToggleActivation' while setting bean property 'tasklet'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponToggleActivation': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: JobRepository must be set
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313)
 at com.mythribuswebservice.MythribusWebserviceApplication.main(MythribusWebserviceApplication.java:15)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#12e0f78': Cannot create inner bean '(inner bean)#693226' of type [org.springframework.batch.core.job.flow.support.StateTransition] while setting bean property 'stateTransitions' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#693226': Cannot create inner bean '(inner bean)#758545' of type [org.springframework.batch.core.job.flow.support.state.StepState] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#758545': Cannot resolve reference to bean 'couponActivation' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponActivation': Cannot resolve reference to bean 'couponToggleActivation' while setting bean property 'tasklet'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponToggleActivation': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: JobRepository must be set
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299)
 ... 16 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#693226': Cannot create inner bean '(inner bean)#758545' of type [org.springframework.batch.core.job.flow.support.state.StepState] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#758545': Cannot resolve reference to bean 'couponActivation' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponActivation': Cannot resolve reference to bean 'couponToggleActivation' while setting bean property 'tasklet'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponToggleActivation': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: JobRepository must be set
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313)
 ... 24 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#758545': Cannot resolve reference to bean 'couponActivation' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponActivation': Cannot resolve reference to bean 'couponToggleActivation' while setting bean property 'tasklet'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponToggleActivation': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: JobRepository must be set
 
 ... 32 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponActivation': Cannot resolve reference to bean 'couponToggleActivation' while setting bean property 'tasklet'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponToggleActivation': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: JobRepository must be set
 
 at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
 ... 40 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'couponToggleActivation': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: JobRepository must be set
 
 ... 50 more
Caused by: java.lang.IllegalArgumentException: JobRepository must be set
 
 ... 55 more
I have removed the StackTrace.

Any Comments.will be appreciable.

2

There are 2 answers

1
Essex Boy On

The error says that couponToggleActivation does not have a JobRepository set.

I assume this refers to the otpJob job.

0
lucky.143 On

Thanks..For your efforts.

After struggling for a long time i was able to find out that there was issue with declaring the Job and Tasklet of couponToggleActivation.

<batch:job id="couponToggleActivation" job-repository="jobRepository">
    <batch:step id="couponActivation">
        <batch:tasklet ref="couponToggleActivation">

        </batch:tasklet>
    </batch:step>
</batch:job>

I have written the job id and tasklet ref as couponToggleActivation just changing the name of the job worked for me.

The issue was that the IOC container was unable to recognize Job id and Tasklet Implementer class ref and was in Ambiguity.

So i Made it .

<batch:job id="couponToggleActivationJob" job-repository="jobRepository">
    <batch:step id="couponActivation">
        <batch:tasklet ref="couponToggleActivation">

        </batch:tasklet>
    </batch:step>
</batch:job>