Spring Batch CommandLineJobRunner在由企业调度程序运行时挂起

时间:2016-04-20 16:22:42

标签: java spring spring-batch scheduler

我们的组织使用Skybot企业计划程序来运行批处理作业。我们最近部署了我们的第一个Spring批处理应用程序,并使用SELECT * FROM (SELECT ParentID, Caption, Name FROM #table) AS t PIVOT ( MAX(t.Name) FOR Caption IN ([Plan], [Content], [Accuracy]) ) AS pvt 作为主类来安排我们的作业运行(Main-Class在我们的jar的清单中定义)。该命令如下所示:

CommandLineJobRunner

在手动执行命令行时,作业运行完美。当调度程序执行相同的命令时,作业立即挂起而在skybot日志中没有输出,并且作业没有完成任何工作。我们调查了可能的权限问题,但都不存在。 spring批处理文档指出java -Dspring.profiles.active=production -jar AppName.jar jobs/jobName.xml jobId 可用于从shell运行预定作业,但我们的所有作业在执行时都会立即挂起。我们怎样解决这个问题?

1 个答案:

答案 0 :(得分:0)

这似乎是CommandLineJobRunner类和Skybot之间的不兼容。在决定用我自己的类替换spring批处理类(加载应用程序上下文,构建JobLauncher等)之后,我查看了source code for CommandLineJobRunner。主要方法是提前调用System.in.available();当我们通过输入命令并按Enter键来运行作业时,标准输入可以从键盘读取换行。另一方面,Skybot作为stdin不会立即阻止,但是没有换行,所以程序无休止地等待输入。

来自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();
    }
}

我们的作业参数是初始命令的所有参数,因此这段代码不必要且有问题。解决方案是自己滚动 - 非常类似于CommandLineJobRunner,但没有与标准输入进行任何交互。