org.springframework.batch.core.launch.NoSuchJobException: No job configuration with the name [longJob] was registered

JAVA/SpringBatch|2020. 4. 2. 20:04

SpringBatch의 활용 및 동작 파악을 위해 끄적 끄적 하고 있는데

 

Job List를 얻으려면 어떻게 해야 하나 살펴보니 여러가지 방법이 있지만

두가지를 활용해봤습니다.

 

첫번째 방법

Job Type에 대해 Injection을 이용하는 방법

 

두번째 방법은 

ListableJobLocator 였습니다.

 

첫번째 방법인 JobType은 List<? extends Job> 이나

Map<String, ? extends Job>//String은 Bean네임 로 인젝션을 받으면

Bean으로 등록된 Job들을 받을수 있었습니다.

 

두번째 방법인 ListableJobLocator는 getJobNames()로 Job의 Name List를 가져오거나

getJob(name)을 통해 Job 객체를 가져올수 있습니다.

하지만, 저처럼 별다른 설정을 하지 않으면 위와 같은 에러를 만날수 있습니다.

@Bean
    public Job longJob() throws DuplicateJobException {
        return jobBuilderFactory.get("longJob").start(longStep()).build();
    }

에러가 발생하는 이유는 JobRegistry에 등록을 하지 않았기 때문인데요

 

해결하는 방법도 다양하겠지만 두가지를 소개 하려고합니다.

 

첫번째 방법 Job을 Bean으로 등록하기전 JobRegistry에 등록

두번째 방법 JobRegistryBeanPostProcessor를 Bean으로 등록하여 Registry에 등록

 

첫번째 방법인 JobRegistry에 등록하기 위해서는 JobRegistry에 register(JobFactory) 메소드를 이용하여 등록할 수 있는데, JobFactory는 ApplicationContextJobFactory 혹은 ReferrenceJobFactory를 통해 등록 하면 됩니다.

 

ApplicationContextJobFactory은 JobName과 ApplicationContextFactory를 받아 Bean으로 등록된 Job을 생성하는 Factory이며(Job을 Bean으로 등록하는 와중에 ApplicationContextJobFactory를 활용한 등록은 불가능 합니다.)

ReferrenceJobFactory는 Job Instance를 받아 그대로 돌려주는 방식으로 동작하는 Factory로 Bean을 등록하는 와중에 활용 할 수 있습니다.

@Bean
    public Job longJob() throws DuplicateJobException {
        Job job = jobBuilderFactory.get("longJob").start(longStep()).build();

        ReferenceJobFactory factory = new ReferenceJobFactory(job);
        jobRegistry.register(factory);
        return job;
    }

다만 이 방법은 Job Bean 선언 마다 register를 불러야 하는 단점과 원하는 Job만 등록할 수 있다는 장점이 있겠습니다.

 

두번째 방법은 JobRegistryBeanPostProcessor를 활용하는 방법이 있습니다.

 

@Bean
	public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
		JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor = new JobRegistryBeanPostProcessor();
		jobRegistryBeanPostProcessor.setJobRegistry(jobRegistry);
		return jobRegistryBeanPostProcessor;
	}

네 끝입니다.

Job마다 등록할 필요 없이 Job Type이 빈으로 등록될때 후처리로 자동으로 JobRegistry에 등록하게 됩니다.

 

 

등록을 하지 않아도 Job Type을 Injection으로 찾아 JobLauncher로 실행도 가능하지만

등록하지 않으면 JobLocator 뿐 아니라 JobOperator도 동작하지 않더군요

예외사항이 생길지 모르겠지만 런타임시 관리를 위해서는 필수로 보입니다.

 

 

댓글()