11

I don't know how to call a Job defined in Spring Batch using CommandLineJobRunner, documentation details are not enough for me.

I've followed the Spring Batch official guide to write Jobs in Spring Batch using Java annotations e.g. @EnableBatchProcessing because I wanted to avoid XML configuration files for the description of the job, the steps, etc.

So far I have:

  • a configuration class (com.package.bla.bla.ClassContainingTheBatchConfiguration see below) where I've put all the stuff defining ItemReader, ItemProcessor, ItemWriter, Job, and Step (with return jobs.get("nameOfTheJob") see below) using a @Bean annotaion.
  • a class with a main method with SpringApplication.run(...) and and annotation with @ImportResource("classpath:META-INF/spring/applicationContext.xml") to import some beans I need when processing the data in the Job.

On the Maven side I am currently using some plugins:

  • maven-jar-plugin specifying <addClasspath>true</addClasspath> and the class containing the main method in the tag <mainClass>
  • maven-assembly-plugin because I would like a unique executable jar containing all the stuff in the dependencies, I am using <phase>package</package> to be able to build the jar in the package phase, I am also using <goal>single</goal> to be able to properly build the jar using the assembly
  • maven-compiler-plugin specifying I am using Java 1.7

I think I've configured all the things I need to configure, however after having a Maven BUILD SUCCESS I am not able to run the job from the command line:

java -cp ./target/JAR_FILE_NAME.jar org.springframework.batch.core.launch.support.CommandLineJobRunner com.package.bla.bla.ClassContainingTheBatchConfiguration nameOfTheJob

Is throwing IOException due to the java.io.FileNotFoundException regarding com.package.bla.bla.ClassContainingTheBatchConfiguration. How should I specify the parameters in the command line in order to get the Job executed?

TPPZ
  • 4,447
  • 10
  • 61
  • 106
  • Documentation 'details' are ridiculous. I can hardly imagine running an existing job based on documentation only. I just wonder what was the learning curve to a guy who created the job... – tishma Jan 19 '21 at 16:17

3 Answers3

2

If you are already using SpringApplication from Spring Boot, why not finish the job and use @EnableAutoConfiguration as well, and also the Maven plugin (see for example this guide)? That way you will get something working pretty quickly and you can always add your own features later.

Dave Syer
  • 56,583
  • 10
  • 155
  • 143
  • Oh I forgot mentioning that the class containing the `main` method is annotated with `@EnableAutoConfiguration`. I actually would like to have some sort of control over the jobs I can run i.e. chose which job should be run by the `SpringApplication.run(...)`. That's why I thought maybe I could use somehow `CommandLineJobRunner` providing an annotated class rather than a XML configuration file. – TPPZ Feb 25 '14 at 17:26
  • 1
    With `@EnableAutoConfiguration` you can set "spring.batch.jobName" (up to RC3) or "spring.batch.jobNames" (since yesterday) to list the jobs to execute (see here: https://github.com/spring-projects/spring-boot/blob/master/docs/howto.md#execute-spring-batch-jobs-on-startup). You can do that in your main method if you prefer but it's probably better to pass it on the command line (a bit like you were trying to do with the CLJR). – Dave Syer Feb 25 '14 at 18:00
  • That sounds like great news! Well how should I specify this `spring.batch.jobName` parameter? I thought I could have set something near `@EnableAutoConfiguration` (which is calling `BatchAutoConfiguration`) but that's not the case. I've set the Spring Boot parent version in Maven to be `1.0.0.RC3`. (I am quite new to Spring and stuck with the documentation and the source code browsing) – TPPZ Feb 25 '14 at 18:38
  • If you're not very familiar with Spring why not try to work through some of [the guides](http://spring.io/guides/)? Externalizing configuration in a Boot application is covered in various places, including [here](https://github.com/spring-projects/spring-boot/tree/master/spring-boot#externalized-configuration). – Dave Syer Feb 25 '14 at 22:05
  • Ok, I've done some tests but I am still not able to pass some parameters from the command line either they are directly property names and values or paths to a properties file. `$ java -jar target/jarName.jar spring.batch.job.names=nonExistingJobName` make me see in the log `2014-02-28 16:32:58.977 [main] INFO org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner - Running default command line with: [spring.batch.job.names=nonExistingJobName]` – TPPZ Feb 28 '14 at 16:31
  • 1
    To add properties to the environment using the command line you need to add "--" to the argument (I'll make that more obvious in the docs). You porobably want `jobNames` not `job.names` as well (but it might work with the period if you're lucky). – Dave Syer Feb 28 '14 at 17:04
  • I've tried both `job.names` and `jobNames` from the command line with a `--` prefix (e.g. `$ java -jar target/jarName.jar --spring.batch.job.names=nonExistingJobName`) and I am still getting an unwanted job executed, e.g. after seeing the previously mentioned log statement, I am also seeing: `2014-02-28 17:13:15.866 [main] INFO org.springframework.batch.core.launch.support.SimpleJobLauncher - Job: [FlowJob: [name=existingJobName]] launched with the following parameters: [{-spring.batch.job.names=nonExistingJobName}] ` Should I set something in the `main` method related to `SpringApplication`? – TPPZ Feb 28 '14 at 17:25
  • You can see the parameters being passed to the job from the command line. To me it looks suspicious that you have "-" in front of the `spring.batch.job.names` (which should be `jobNames`). Is "nonExistingJobName" an actual job name in your context? I'm a bit confused about that. If you can publish your code somewhere I'll have a look. – Dave Syer Feb 28 '14 at 17:51
  • Well I do not own the rights on this code, I can not publish it. Thanks for all the details you provided so far, they have been really helpful. – TPPZ Mar 05 '14 at 23:15
  • What maven dependency is needed for `@EnableBatchProcessing` ? I tried with ` org.springframework.batch spring-batch-core 3.0.4.RELEASE ` but it doesn't contain that annotation. – Jonas Jun 05 '15 at 08:21
  • I think it does. Look again. Check your spelling or something. – Dave Syer Jun 05 '15 at 11:00
1

If the first argument to the CommandLineJobRunner is your @Configuration FQCN instead of a resource path, the ClassPathXmlApplicationContext constructor that's called from the CommandLineJobRunner's start() method will break.

int start(String jobPath, String jobIdentifier, String[] parameters, Set<String> opts) {

    ConfigurableApplicationContext context = null;

    try {
        context = new ClassPathXmlApplicationContext(jobPath);

If you've already written a class with a main(), that replaces the CLJR, you shouldn't be passing CLJR as the class name in the command line. Pass that instead.

Emerson Farrugia
  • 11,153
  • 5
  • 43
  • 51
  • Yeah I suspected that, I was not sure. Well, in the class containing the `main` method I would like to explicitly specify which job should be run. I can not find a way using a `main` method with `SpringApplication.run(...)` though. – TPPZ Feb 25 '14 at 17:28
  • 1
    `java -jar ... --spring.batch.jobNames=myJobName` didn't work? – Dave Syer Mar 06 '14 at 07:18
  • 1
    @DaveSyer : This command looks good. How do I pass job parameters and how do I infer the same in the job config bean ? – PavanSandeep Oct 17 '15 at 13:34
0

dont use spring.batch.job.enabled=false then run using java -jar [jar-files] --spring.batch.job.names=[job-name]

  • 2
    Hi AndreLucky - please will you add a little more detail to your answer? I would love to know HOW and WHY this works? – user230910 Jul 08 '19 at 04:40