본문 바로가기
Dev & Tech/Web

IntelliJ에서 Spring Boot 배치 로컬 테스트 – bootRun --args로 날짜 파라미터 실행하는 방법

by 루루모먼트 2026. 3. 3.
반응형
IntelliJ에서 Spring Boot 배치 로컬 테스트 – bootRun --args로 날짜 파라미터 실행하는 방법

IntelliJ에서 Spring Boot 배치 로컬 테스트 – bootRun --args로 날짜 파라미터 실행하는 방법

운영 환경에서 Apache Airflow로 스케줄링하는 Spring Boot 배치를 로컬에서 테스트할 때, IntelliJ Gradle Run Configuration의 bootRun --args 옵션을 활용하면 Airflow 없이도 원하는 날짜 조건을 그대로 재현할 수 있습니다. 이 글에서는 실제로 동작하는 방법인 bootRun --args='--job_name=... collectYmd=... compYmd=...' 형식을 중심으로 설정 방법과 주의사항을 정리합니다.
목차
1. 운영(Airflow)과 로컬(bootRun) 실행 방식 비교
2. IntelliJ Run Configuration --args 설정 방법
3. --args 파라미터 형식과 규칙
4. Spring Boot 배치 코드에서 파라미터 수신
5. 자주 발생하는 오류와 해결 방법

#1. 운영(Airflow)과 로컬(bootRun) 실행 방식 비교
1) 두 환경의 실행 방식 차이
운영과 로컬은 실행 주체가 다르지만, 날짜를 포함한 파라미터를 args로 전달한다는 구조는 동일합니다. 로컬 테스트의 핵심은 Airflow가 JAR에 넘기는 args를 bootRun에서 그대로 재현하는 것입니다.
구분운영 환경 (Airflow)로컬 환경 (IntelliJ bootRun)
실행 주체Airflow Scheduler / DAG개발자 (IntelliJ Run Configuration)
실행 명령java -jar batch.jar --job_name=... collectYmd=...bootRun --args='--job_name=... collectYmd=...'
날짜 값 출처Airflow 템플릿 변수 ({{ ds_nodash }})개발자가 직접 날짜 입력
빌드 결과물배포된 JAR 파일 직접 실행소스 기반 즉시 실행 (JAR 빌드 불필요)
· · · · ·
2) Airflow에서 배치를 실행하는 구조
운영에서 Airflow는 보통 아래와 같이 BashOperator로 JAR를 실행하면서 날짜 파라미터를 전달합니다. 로컬 테스트 시 이 구조를 bootRun --args로 동일하게 재현합니다.
# Airflow DAG 예시 (운영 환경)
run_batch = BashOperator(
    task_id='run_spring_batch',
    bash_command="""
        java -jar /app/batch.jar \
            --job_name=job_TranRconcl \
            collectYmd={{ ds_nodash }} \
            compYmd={{ macros.ds_add(ds, -1) | replace('-', '') }}
    """
,
)
# ds_nodash 예시: 20260228 / macros.ds_add(ds, -1): 전일 날짜

#2. IntelliJ Run Configuration --args 설정 방법
1) Gradle Run Configuration 생성 및 --args 입력
IntelliJ에서 아래 순서로 Run Configuration을 생성하고 --args 옵션을 입력합니다.
(1) Run Configuration 생성 순서
① 상단 메뉴 Run → Edit Configurations 클릭
② 좌측 상단 + 버튼 클릭 → Gradle 선택
Name 입력란에 식별하기 쉬운 이름 입력 (예: admin-ba [bootRun])
Gradle project에 해당 모듈 선택 (예: admin-ba)
Run 입력란에 아래 형식으로 입력
bootRun --args='--job_name=job_TranRconcl collectYmd=20260228 compYmd=20260227'
Apply → OK 클릭 후 상단 Run 버튼(▶)으로 실행
⑦ 날짜를 바꿀 때는 Run 입력란의 날짜 숫자만 수정 후 재실행
· · · · ·
2) 날짜별 Configuration을 여러 개 저장하는 방법
과거 날짜 재처리 검증처럼 날짜를 바꿔가며 반복 테스트할 때는 Configuration을 여러 개 저장해 두면 편리합니다.
Configuration 이름Run 입력값 (--args 부분)용도
bootRun-0228bootRun --args='--job_name=job_TranRconcl collectYmd=20260228 compYmd=20260227'2/28 배치 테스트
bootRun-0301bootRun --args='--job_name=job_TranRconcl collectYmd=20260301 compYmd=20260228'3/1 배치 테스트
bootRun-reprocessbootRun --args='--job_name=job_TranRconcl collectYmd=20260101 compYmd=20251231'특정 과거 날짜 재처리

#3. --args 파라미터 형식과 규칙
1) --args 파라미터 작성 형식
bootRun --args 안에 들어가는 파라미터는 Spring Boot가 실행될 때 main 메서드의 args 배열로 전달됩니다. 파라미터 종류에 따라 앞에 --를 붙이는 규칙이 다릅니다.
파라미터 종류형식예시
Spring 옵션 인수
(Spring properties)
--key=value--job_name=job_TranRconcl
비옵션 인수
(Non-option args)
key=value (-- 없음)collectYmd=20260228
Spring 환경 설정--spring.profiles.active=...--spring.profiles.active=local
· · · · ·
2) 실제 동작하는 --args 형식 예시
사진에서 확인된 실제 동작 형식입니다. --args 내부를 작은따옴표(' ')로 감싸고, 여러 파라미터는 공백으로 구분합니다.
// 기본 형식 (실제 동작 확인)
bootRun --args='--job_name=job_TranRconcl collectYmd=20260228 compYmd=20260227'

// 로컬 프로파일 추가 시
bootRun --args='--job_name=job_TranRconcl collectYmd=20260228 compYmd=20260227 --spring.profiles.active=local'

// 터미널에서 직접 실행할 경우 (Windows는 작은따옴표 대신 큰따옴표)
./gradlew bootRun --args="--job_name=job_TranRconcl collectYmd=20260228 compYmd=20260227"
· · · · ·
3) build.gradle 별도 설정 없이 동작하는 이유
--args는 Gradle Spring Boot 플러그인이 기본 제공하는 옵션입니다. build.gradle에 별도 bootRun 블록을 추가하지 않아도 IntelliJ Run Configuration의 Run 입력란에서 바로 사용할 수 있습니다.

단, Spring Boot Gradle 플러그인 2.2.0 이상에서만 --args 옵션이 지원됩니다. 그 이하 버전에서는 build.gradle에서 args를 직접 설정해야 합니다.

#4. Spring Boot 배치 코드에서 파라미터 수신
1) ApplicationRunner에서 파라미터 수신 및 Job 실행
--args로 전달된 파라미터는 ApplicationArguments를 통해 수신합니다. --key=value 형식은 getOptionValues()로, key=value 형식(비옵션 인수)은 getNonOptionArgs()로 꺼냅니다.
@Component
@RequiredArgsConstructor
public class BatchJobRunner implements ApplicationRunner {

    private final JobLauncher jobLauncher;
    private final Job sampleJob;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        // 비옵션 인수(key=value) 파싱: collectYmd=20260228 compYmd=20260227
        Map<String, String> params = new HashMap<>();
        for (String arg : args.getNonOptionArgs()) {
            String[] kv = arg.split("=", 2);
            if (kv.length == 2) params.put(kv[0], kv[1]);
        }

        String collectYmd = params.getOrDefault("collectYmd",
            LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        String compYmd = params.getOrDefault("compYmd",
            LocalDate.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd")));

        JobParameters jobParams = new JobParametersBuilder()
            .addString("collectYmd", collectYmd)
            .addString("compYmd", compYmd)
            // 로컬 재실행 허용을 위해 run.id 추가
            .addLong("run.id", System.currentTimeMillis())
            .toJobParameters();

        jobLauncher.run(sampleJob, jobParams);
    }
}
· · · · ·
2) Step에서 날짜 파라미터 사용
Step 내에서는 반드시 @StepScope를 선언한 뒤 @Value("#{jobParameters['collectYmd']}")로 날짜를 주입받습니다.
@StepScope
@Bean
public Tasklet reconcileTasklet(
    @Value("#{jobParameters['collectYmd']}") String collectYmd,
    @Value("#{jobParameters['compYmd']}") String compYmd) {

    return (contribution, chunkContext) -> {
        System.out.println("수집 기준일: " + collectYmd);
        System.out.println("비교 기준일: " + compYmd);
        return RepeatStatus.FINISHED;
    };
}

#5. 자주 발생하는 오류와 해결 방법
1) 오류 유형별 원인과 해결
오류 / 증상원인해결 방법
파라미터 값이 null로 수신됨key=value 형식을 getOptionValues()로 받으려 함비옵션 인수는 getNonOptionArgs()로 파싱
JobInstanceAlreadyCompleteException동일 JobParameters로 완료된 Job 재실행 시도JobParametersBuilder에 run.id(currentTimeMillis) 추가
Unrecognized option: --argsSpring Boot Gradle 플러그인 2.2.0 미만플러그인 버전 업그레이드 또는 build.gradle args 방식으로 변경
파라미터가 잘못 분리됨--args 내부 공백 처리 오류--args='...' 작은따옴표로 전체를 감싸고 내부는 공백으로만 구분
@StepScope 빈 생성 오류@StepScope 누락 또는 @Bean 메서드에서 직접 호출@StepScope + @Bean 함께 선언, 직접 호출하지 않고 Spring이 주입하도록 설정
· · · · ·
2) --args 형식별 수신 방법 정리
--job_name=...처럼 앞에 --가 붙으면 Spring이 옵션 인수로 처리하고, collectYmd=...처럼 --가 없으면 비옵션 인수로 처리합니다. 수신 방법이 다르므로 주의가 필요합니다.
// --args='--job_name=xxx collectYmd=20260228 compYmd=20260227' 기준

// 1) 옵션 인수 수신 (앞에 -- 있음)
String jobName = args.getOptionValues("job_name").get(0);
// → "job_TranRconcl"

// 2) 비옵션 인수 수신 (앞에 -- 없음: key=value)
List<String> nonOptions = args.getNonOptionArgs();
// → ["collectYmd=20260228", "compYmd=20260227"]
// split("=", 2)으로 key/value 분리하여 사용

마무리
Airflow 없이 IntelliJ에서 Spring Boot 배치를 로컬 테스트할 때 가장 간단하고 확실한 방법은 Gradle Run Configuration의 Run 입력란에 아래 형식을 직접 입력하는 것입니다.

bootRun --args='--job_name=job_TranRconcl collectYmd=20260228 compYmd=20260227'
--job_name처럼 -- 접두사가 붙은 옵션 인수getOptionValues()로, collectYmd처럼 -- 없는 비옵션 인수getNonOptionArgs()를 파싱하여 수신합니다. 날짜별로 Run Configuration을 저장해 두면 과거 날짜 재처리 시나리오도 클릭 한 번으로 빠르게 검증할 수 있습니다.
긴 글 읽어주셔서 감사합니다.

끝.


반응형