Spring Batch CommandLineJobRunner зависает при запуске планировщиком предприятия
Наша организация использует планировщик предприятия Skybot для запуска пакетных заданий. Недавно мы развернули наше первое весеннее пакетное приложение и запланировали запуск наших заданий с использованием CommandLineJobRunner
в качестве основного класса (Main-Class определен в манифесте нашей банки). Команда выглядит так:
java -Dspring.profiles.active=production -jar AppName.jar jobs/jobName.xml jobId
При выполнении в командной строке вручную задания выполняются идеально. Когда та же команда выполняется планировщиком, задание немедленно зависает без вывода в журналах Skybot и без выполнения задания. Мы исследовали возможные проблемы с разрешениями, но ни одна из них не существует. В весенней партии говорится, что CommandLineJobRunner
доступен для запуска запланированных заданий из оболочки, но все наши задания зависают сразу после выполнения. Как мы можем решить это?
1 ответ
Похоже, что это несовместимость между классом CommandLineJobRunner и Skybot. После принятия решения о замене класса Spring Batch своим собственным (загрузка контекста приложения, создание JobLauncher и т. Д.) Я посмотрел исходный код CommandLineJobRunner. Основной метод имеет ранний вызов System.in.available()
; когда мы запускаем задание, набирая команду и нажимая ввод, стандартный ввод может читать перевод строки с клавиатуры. С другой стороны, 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, но без какого-либо взаимодействия со стандартным вводом.