1
votes

Our organization uses the Skybot enterprise scheduler to run batch jobs. We recently deployed our first spring batch app, and scheduled our jobs to run using CommandLineJobRunner as the main class (Main-Class is defined in the manifest of our jar). The command looks like this:

java -Dspring.profiles.active=production -jar AppName.jar jobs/jobName.xml jobId

When executed on the command line manually, the jobs run perfectly. When the same command is executed by the scheduler, the job immediately hangs with no output in the skybot logs, and no work done by the job. We investigated possible permissions problems, but none exist. The spring batch documentation states that CommandLineJobRunner is available for the purpose of running scheduled jobs from the shell, but all our jobs are hanging immediately upon execution. How can we solve this?

1

1 Answers

1
votes

This appears to be an incompatibility between the CommandLineJobRunner class and Skybot. After deciding to replace the spring batch class with my own (loading the application context, constructing a JobLauncher, etc), I looked at the source code for CommandLineJobRunner. The main method has an early call to System.in.available(); when we run the job by typing the command and hitting enter, the standard input can read the line feed from the keyboard. Skybot as stdin, on the other hand, does not immediately block, but no line feed follows, so the program waits interminably for input.

From the main method of org.springframework.batch.core.launch.support.CommandLineJobRunner:

if (System.in.available() > 0) {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String line = " ";
    while (line != null) {
        if (!line.startsWith("#") && StringUtils.hasText(line)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Stdin arg: " + line);
            }
            newargs.add(line);
        }
        line = reader.readLine();
    }
}

Our job parameters are all arguments to the initial command, so this code was unnecessary and problematic. The solution was to roll our own - very similar to CommandLineJobRunner but without any interaction with the standard input.