So below sample java class configuration will get the CRON job expression from the database dynamically. So far it works only in 1 job. However, I have another job and tried adding it by invoking addTriggerTask method but job failed due to this error. Any recommendation how we can trigger multiple jobs?
ERROR: required a single bean, but 2 were found
Action: Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
@Configuration
@EnableScheduling
public class DynamicScheduler implements SchedulingConfigurer {
private static Logger LOGGER = LoggerFactory.getLogger(DynamicScheduler.class);
@Autowired
ConfigRepo repo;
@Autowired
JobLauncher jobLauncher;
@Autowired
private Job job;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(() -> executeJob("job1"), t -> {
CronTrigger crontrigger = new CronTrigger(repo.findById("cronExpressionJob1").get().getConfigValue());
return crontrigger.nextExecutionTime(t);
});
}
public void executeJob(String jobName) {
try {
JobParameters jobParameters = new JobParametersBuilder()
.addString(jobName, String.valueOf(System.currentTimeMillis())).toJobParameters();
jobLauncher.run(job, jobParameters);
} catch (Exception e) {
LOGGER.error("Failed due to exception thrown.", e);
}
}
}
In your current code, you are using @Autowired
to inject a Job
into DynamicScheduler
. This is unambiguous when you only have a single job, but as soon as you add another job Spring cannot disambiguate which job you want injected.
That's why you are seeing the error:
ERROR: required a single bean, but 2 were found
Action: Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
If you want to handle multiple jobs, then I suggest removing @Autowired private Job job;
from your class and use a JobRegistry to look up your Job
by name as a local variable. Then pass that Job
along with its JobParameters
to jobLauncher.run()
.
// get JobParameters for jobName
Job job = jobRegistry.getJob( jobName );
jobLauncher.run( job, jobParameters );