강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

다온님의 프로필 이미지
다온

작성한 질문수

죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.

2장. 작전1: FlatFileItemReader (시스템의 마지막 기록을 읽어내다 ☠️)

MR.kill-9 첫번째 예제 코드 실습하면서 궁굼한점이 생겼다.

작성

·

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

KILL-9님의 프로필 이미지
KILL-9
지식공유자

MR.다온

예제는 정상 실행되는것으로 확인되었다 혹시 예제 실행시 사용한 명령어를 알 수 있을까

추가로
application.yml 설정과 프로젝트에 DefaultBatchConfiguration을 상속한 코드가 존재하는지 확인을 부탁한다.


1

KILL-9님의 프로필 이미지
KILL-9
지식공유자

$ 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에서 해당 파라미터를 인식하지 못할 수 있습니다.

해결 방법 제안

  1. StepScope 사용 확인:

    • StepScope를 사용하여 Bean을 정의했는지 확인하세요. StepScope는 스텝 내에서만 유효한 상태를 유지하며, JobParameters를 인식할 수 있도록 해줍니다.
  2. SpringApplicationBuilder 사용:

    • SpringApplication.run() 대신 SpringApplicationBuilder를 활용하여 명령행 인수를 설정할 수 있습니다. 예를 들어:
     new SpringApplicationBuilder(KillBatchSystemApplication.class)
         .properties("spring.batch.job.enabled=false") // 자동 실행 방지
         .run(args);
    
  3. 애플리케이션 차원에서의 인자 전달:

    • 인자를 CLI에서 직접 전달하는 대신, application.yml 또는 application.properties를 사용하여 기본값을 설정하는 방법도 고려해볼 수 있습니다.
  4. JobLauncherApplicationRunner 비활성화:

    • @SpringBootApplication에 명시적으로 spring.batch.job.enabled=false 속성을 설정하면, 기본적인 자동 실행 동작을 방지하고, 원하는 시점에 Job을 실행할 수 있게 됩니다.
  5. 커맨드라인 인자 전달 확인:

    • MacOS 터미널을 사용 중이라면, CLI 인자 전달 방식이 운영체제 및 쉘 설정에 맞는지, 인자 값이 정확하게 전달되고 있는지 체크해보세요.

CLI로 JobParameter 수집 사례

CLI로 전달된 매개변수를 안전하게 받고 이를 StepScope에서 활용하기 위해 로컬 변수나 외부 설정 파일 없이 직접 명령행에서 JobParameters를 사용하는 예시입니다.

만일 실행 중 환경설정에 대한 더 많은 정보를 원하시면 추가적으로 스프링 공식 문서를 참조하시길 권장합니다. 이는 JobParameter를 활용하여 다른 사례와 실제 코드에서 다양한 인자 수집 및 전달 방법을 배울 수 있는 유용한 자료입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

다온님의 프로필 이미지
다온

작성한 질문수

질문하기