작성
·
11
1
강의 예제를 따라가면서 SystemFailureJobConfig 배치를 실행했는데, 계속 FlatFileItemReader에서 JobParameter로 전달한 inputFile이 null로 들어오는 문제가 발생했다.
정확하게는 Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.file.FlatFileItemReader]: Factory method 'systemFailureItemReader' threw exception with message: Path must not be null
이 오류 였으며,
public FlatFileItemReader<SystemFailure> systemFailureItemReader(
@Value("#{jobParameters['inputFile']}") String inputFile) {
log.info("오잉 Reader inputFile: " + inputFile); // null
return new FlatFileItemReaderBuilder<SystemFailure>()
.name("systemFailureItemReader") //여기서 path not null 오류 발생
.resource(new FileSystemResource(inputFile))
.delimited()
.delimiter(",")
.names("errorId",
"errorDateTime",
"severity",
"processId",
"errorMessage")
.targetType(SystemFailure.class)
.linesToSkip(1)
.build();
}
.name("systemFailureItemReader")
이 위치에서 발생하고 있었다. 그리고 line numbers are likely diverged. try to find the current location inside 'SystemFailureJobConfig. systemFaliureItemReader()'
이 메시지도 함께 보였다.
GPT에 물어봐서 해결이 되긴 했는데, KillBatchSystemApplication에서 CommandLineRunner를 구현하고 직접 경로를 지정해주었다.
@SpringBootApplication
@AllArgsConstructor
public class KillBatchSystemApplication implements CommandLineRunner {
private final JobLauncher jobLauncher;
private final Job systemFailureJob;
public static void main(String[] args) {
SpringApplication.run(KillBatchSystemApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
JobParameters params = new JobParametersBuilder()
.addString("inputFile", "/Users//Desktop/kill-batch-system2/system-failures.csv")
.toJobParameters();
jobLauncher.run(systemFailureJob, params);
}
}
실무에서는 CLI로 파라미터를 전달하는것이 핵심이라 했던걸로 기억한다.
CLI로 전달한 JobParameter를 StepScope Bean에서 안전하게 받는 다른 방법은 없나??
아 지금 작업도구는 MacOS M1, Spring Boot 3.4.7 이다.
연휴 잘 보내길 바란다.
답변 3
1
MR.다온
예제는 정상 실행되는것으로 확인되었다 혹시 예제 실행시 사용한 명령어를 알 수 있을까
추가로
application.yml 설정과 프로젝트에 DefaultBatchConfiguration을 상속한 코드가 존재하는지 확인을 부탁한다.
1
$ cat > student_response.md
좋은 질문이다
GPT가 만들어준 해결책이라...
CommandLineRunner로 우회했구나. 작동은 하겠지만 이건 근본 원인을 못 찾은 거다.
왜 CommandLineRunner는 임시방편인가
파라미터를 하드코딩하면 배포 때마다 코드 수정 필요
CLI 파라미터 전달이 정석
9시쯤 정확한 원인 찾아주겠다
대신 그 전에, application.yml 설정을 보여달라 프로젝트에 DefaultBatchConfiguration을 상속한 코드가 있는지도 확인을 부탁한다.
$ ps aux | grep "rest"
kill-9 nobody is resting here
연휴라..
시스템 종결자에게 휴식 따위 없다.
연휴 동안 열심히 공부하고 질문해 나를 괴롭혀라.
$ uptime
KILL-9 has been running for 99999 days without rest
0
안녕하세요, 인프런 AI 인턴입니다.
minjirj님께서 겪고 계시는 문제는 Spring Batch에서 CLI로 전달된 JobParameter를 StepScope Bean에서 수신하지 못하는 것입니다. 이 문제는 일반적으로 Spring Boot 애플리케이션에서 배치 작업을 위한 JobParameter 전달이 제대로 설정되지 않았을 때 발생할 수 있습니다.
기본적으로 Spring Batch에서 CLI를 통해 전달된 JobParameters는 배치 실행 중에 사용되지만, 특정 설정이 없으면 StepScope에서 해당 파라미터를 인식하지 못할 수 있습니다.
StepScope 사용 확인:
SpringApplicationBuilder 사용:
SpringApplication.run()
대신 SpringApplicationBuilder
를 활용하여 명령행 인수를 설정할 수 있습니다. 예를 들어: new SpringApplicationBuilder(KillBatchSystemApplication.class)
.properties("spring.batch.job.enabled=false") // 자동 실행 방지
.run(args);
애플리케이션 차원에서의 인자 전달:
application.yml
또는 application.properties
를 사용하여 기본값을 설정하는 방법도 고려해볼 수 있습니다.JobLauncherApplicationRunner 비활성화:
@SpringBootApplication
에 명시적으로 spring.batch.job.enabled=false
속성을 설정하면, 기본적인 자동 실행 동작을 방지하고, 원하는 시점에 Job을 실행할 수 있게 됩니다.커맨드라인 인자 전달 확인:
CLI로 전달된 매개변수를 안전하게 받고 이를 StepScope에서 활용하기 위해 로컬 변수나 외부 설정 파일 없이 직접 명령행에서 JobParameters를 사용하는 예시입니다.
만일 실행 중 환경설정에 대한 더 많은 정보를 원하시면 추가적으로 스프링 공식 문서를 참조하시길 권장합니다. 이는 JobParameter를 활용하여 다른 사례와 실제 코드에서 다양한 인자 수집 및 전달 방법을 배울 수 있는 유용한 자료입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.