1
votes

I am creating a very generic Spring Batch Application where I read a lot of configurations from YAML files and I create jobs dynamically and register the Jobs like below,

jobRegistry.register(new ReferenceJobFactory(job));

All this is done in Configuration Class. After which I launch all the jobs like below,

jobs.forEach(j -> {
            Job job;
            try {
                job = jobRegistry.getJob(j);
                JobExecution jobExecution = jobLauncher.run(job, jobParameters);
                jobExecutions.add(jobExecution);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

All is fine till here, all jobs gets executed and completed successfully and JobRepository is also updated with 'COMPLETED' status. After this, the Spring Batch application continues to run and does not exit. I don't know how to exit the spring batch application once all the jobs are completed.

I followed from some other thread to do below,

ConfigurableApplicationContext run = SpringApplication.run(ChpCgmsReplicationApplication.class, args);
        System.exit(SpringApplication.exit(run));

This works but the problem is it doesn't wait for all the jobs, The very first job when it completes, the application exits. How do I make this wait till all the jobs are completed and then exit.

2
Have you tried using property spring.main.web-application-type: none ? - Ramachandran Murugaian
Yes, tried it, doesn't work. - Bharat Nanwani
Have you tried close() method from ApplicationContext instead of exit. SpringApplication.run(EanApplication.class, args).close(); - Ramachandran Murugaian
close() method closes the context before even jobs start. This doesn't work either. - Bharat Nanwani
Do you have a ThreadPoolTaskExecutor bean (probably used in your job launcher) preventing your app from exiting? - Mahmoud Ben Hassine

2 Answers

0
votes

Has the problem something do deal with spring boot running jobs on startup feature ? This could be the cause of the problem if your jobs are declared as spring beans.

0
votes

Fundamentally, how does Spring Batch know that "all the jobs are done"? You dynamically registered the jobs, so it's possible that you may still register more.

You can wait until, according to your code, all the required jobs are complete, and then close the application, eg: applicationContext.close(). How you track when all the jobs are complete will depend on how your jobs run, but it could be as simple as a counter, or CountDownLatch.

Something like this

int jobsCount = ...
CountDownLatch doneSignal = new CountDownLatch(jobsCount);

jobs.forEach(j -> {
            // ...
            doneSignal.countDown();
        });

ConfigurableApplicationContext run = SpringApplication.run(...);
doneSignal.await();
SpringApplication.exit(run);