Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No qualifying bean of type 'org.springframework.batch.core.Job' available: expected single matching bean but found 2:

I have 2 jobs running in single spring batch application based on input parameters and it is working successfully. But when i run my test case, i'm getting the below error. I'm using gradle to build my application.

No qualifying bean of type 'org.springframework.batch.core.Job' available: expected single matching bean but found 2: pureRedDataProcessingJob,pcsMasterProcessingJob

Test class:

import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.ConfigFileApplicationContextInitializer;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**

 * 
 * @author 
 *
 */
@ContextConfiguration(classes = {UidBatchApplication.class, JobLauncherTestUtils.class}, 
initializers = ConfigFileApplicationContextInitializer.class)
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(locations = {"classpath:application-test.properties"})
@Configuration
@ActiveProfiles("test")
@Profile("test")
@TestConfiguration
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)

@EnableAutoConfiguration

public class UidBatchApplicationTest {


    @Autowired
    public JobLauncherTestUtils jobLauncherTestUtils;


    @Test
    public void launchJob() throws Exception {
        JobParameters params = new JobParametersBuilder().addString("jobName", "pcsMasterProcessingJob").toJobParameters();
        jobLauncherTestUtils.launchJob(params);
    }

}

Main class configuration:

/*

 */



import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import javax.sql.DataSource;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.MultiResourceItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;




@Configuration
@ConfigurationProperties
@EnableBatchProcessing

public class UidApplicationConfiguration{

    @Autowired
    private DataSource mariaDb;

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public JobExecutionListener listener() {
        return new JobCompletionNotificationListener();
    }

    @Bean
    @Qualifier("pureRedDataProcessingJob")
    public Job pureRedDataProcessingJob() {
        return jobBuilderFactory.get(UidConstants.PURE_RED_JOB)
                .incrementer(new RunIdIncrementer()).listener(listener())
                .flow(pureRedStep()).end().build();
    }

    @Bean
    public Step pureRedStep() {
        return stepBuilderFactory.get("pureRedStep").<PureRedBean, PureRedBean> chunk(1)
                .reader(multiResourcePureRedReader()).processor(pureRedProcessor()).writer(pureRedWriter()).faultTolerant()
                .build();
    }

    @Bean
    public MultiResourceItemReader<PureRedBean> multiResourcePureRedReader()
    {
        MultiResourceItemReader<PureRedBean> resourceItemReader = new MultiResourceItemReader<>();
        resourceItemReader.setResources(getPureredFilePath());
        resourceItemReader.setDelegate(pureRedReader());
        return resourceItemReader;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FlatFileItemReader<PureRedBean> pureRedReader()
    {
        String[] namesArray = {"circularType","rotoKey","xyCoordinate","xyCoordinate","xyCoordinate","adPrintVerNum",
                "adStartDttm","pageNum","itemWic","upc","headLineCopy","bodyCopy","xyCoordinate","pluCode",
                "vendorName","xyCoordinate","xyCoordinate","xyCoordinate","imageFileName","xyCoordinate",
                "offerPrice","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate",
                "quantity","getFree","rewardSpend","rewardPoints","rewardQuantity","percentOff","offerLimit",
                "templateName","adPriceVerbiage","rewardVerbiage","fsiVerbiage","mirVerbiage",
                "ivcVerbiage","retailVerbiage","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate",
                "sevenPartKey","fillerThree","largeImage","xyCoordinate","xyCoordinate","xyCoordinate","xyCoordinate",
                "summary","additionalDealInfo","disclaimer","smallImage"};
        PureredBeanWrapperFieldSetMapper beanWrapper = new PureredBeanWrapperFieldSetMapper();
        beanWrapper.setTargetType(PureRedBean.class);
        DefaultLineMapper linemapper = new DefaultLineMapper();
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(UidConstants.CSV_DELIMITER);
        tokenizer.setNames(namesArray);
        linemapper.setLineTokenizer(tokenizer );
        beanWrapper.setDistanceLimit(0);
        linemapper.setFieldSetMapper(beanWrapper);

        //Create reader instance
        FlatFileItemReader<PureRedBean> reader = new FlatFileItemReader<>();         
        reader.setLineMapper(linemapper);
        return reader;
    }

    @Bean
    public ItemWriter<PureRedBean> pureRedWriter() {        
        JdbcBatchItemWriter<PureRedBean> writer = new JdbcBatchItemWriter<>();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<PureRedBean>());
        writer.setSql(pureredInsertQuery);      
        writer.setDataSource(mariaDb);
        return writer;
    }

    @Bean
    public PureRedProcessor pureRedProcessor() {
        return new PureRedProcessor();
    }

    @Bean
    @Qualifier("pcsMasterProcessingJob")
    public Job pcsMasterProcessingJob() {
        return jobBuilderFactory.get(UidConstants.PCS_MASTER_JOB)
                .incrementer(new RunIdIncrementer()).listener(listener())
                .flow(masterStep()).end().build();
    }

    @Bean
    public Step masterStep() {
        return stepBuilderFactory.get("masterStep").<UniqueIdMasterBean, UniqueIdMasterBean> chunk(1)
                .reader(multiResourceItemReader()).processor(masterProcessor()).writer(writer()).faultTolerant()
                .build();
    }

    @Bean
    public MultiResourceItemReader<UniqueIdMasterBean> multiResourceItemReader()
    {
        MultiResourceItemReader<UniqueIdMasterBean> resourceItemReader = new MultiResourceItemReader<>();
        resourceItemReader.setResources(getFilePath());
        resourceItemReader.setDelegate(reader());
        return resourceItemReader;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FlatFileItemReader<UniqueIdMasterBean> reader()
    {
        String[] namesArray = {"uniqueId","spotSeqNum","adTypeCd","adMarketCd","adStartDttm","adExpiryDttm",
                "adEventType","adSeqNum","adVerCd","adVerSeqNum","adPrintVerNum","adLoyaltyOfferCd","adItemCouponNum",
                "adItemLayoutPosNum","adItemPageNum","adItemRetailMultiple","adItemRetailPrice","adItemSingleUnitPrice",
                "adItemAltPriceMult","adItemAltPrice","adItemAmtOff","adItemPercentOff","adPageTypeCd","minOrderValue",
                "rewardType","offerValue","loyaltyPoints","targetedFlag","","categoryLevelTwo","adFillerOne",
                "adFillerTwo","adFillerThree","statusFlagOne","statusFlagTwo"};
        BeanWrapperFieldSetMapperCustom beanWrapper = new BeanWrapperFieldSetMapperCustom();
        beanWrapper.setTargetType(UniqueIdMasterBean.class);
        DefaultLineMapper linemapper = new DefaultLineMapper();
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(UidConstants.CSV_DELIMITER);
        tokenizer.setNames(namesArray);
        linemapper.setLineTokenizer(tokenizer );
        linemapper.setFieldSetMapper(beanWrapper);

        //Create reader instance
        FlatFileItemReader<UniqueIdMasterBean> reader = new FlatFileItemReader<>();      
        reader.setLineMapper(linemapper);
        return reader;
    }

    @Bean
    public ItemWriter<UniqueIdMasterBean> writer() {        
        JdbcBatchItemWriter<UniqueIdMasterBean> writer = new JdbcBatchItemWriter<>();
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<UniqueIdMasterBean>());
        writer.setSql(insertQuery);     
        writer.setDataSource(mariaDb);
        return writer;
    }

    @Bean
    public MasterProcessor masterProcessor() {
        return new MasterProcessor();
    }

    @Value("${master.filePath}")
    private Resource[] filePath;
    @Value("${master.insertQuery}")
    private String insertQuery;
    @Value("${purered.filePath}")
    private Resource[] pureredFilePath;
    @Value("${purered.insertQuery}")
    private String pureredInsertQuery;
    @Value("${categoryList}")
    private String categoryList;
    private Map<String,String> categoryMap;

    public Resource[] getPureredFilePath() {
        return pureredFilePath;
    }

    public Resource[] getFilePath() {
        return filePath;
    }

    public void setCategoryList(String categoryList) {
        this.categoryList = categoryList;
    }

    /**
     * @return the clientTagsMap
     */
    public Map<String, String> getCategoryMap() {
        if(null == categoryMap){
            categoryMap = new HashMap<>();
            int count = 0;
            String current = "";
            String value = null;
            String key = null ;
            StringTokenizer tok = new StringTokenizer(categoryList, ",=");
            while (tok.hasMoreTokens()) {
                current = tok.nextToken();
                // the first token in the pair is the key
                if (count%(PCSConstants.KEY_LENGTH)==1){
                    value =  current;
                    categoryMap.put(key, value);
                }else{
                    // the second is the value
                    key = current;
                }
                count++;
            }
        }
        return categoryMap;
    }
}

Could someone help me please.

like image 425
Parthiban Avatar asked Nov 05 '18 07:11

Parthiban


People also ask

How do I fix no qualifying bean of type?

The error is “expected at least 1 bean which qualifies as autowire candidate.” The solution is to add the injection class in the ApplicationContext using annotation @Component. The exception “NoSuchBeanDefinitionException: No qualifying bean of type” is resolved if the annotation @Component is added in the Lion class.

What is NoSuchBeanDefinitionException?

This is a common exception thrown by the BeanFactory when trying to resolve a bean that simply isn't defined in the Spring Context. We'll illustrate the possible causes for this problem and the available solutions.


1 Answers

You may need to manually configure JobLauncherTestUtils. This looks like similar to the thread here Spring Batch JUnit test for multiple jobs

Look into the code of JobLauncherTestUtils, which is causing the issue.

@Autowired
    public void setJob(Job job) {
        this.job = job;
    }
like image 92
greengreyblue Avatar answered Oct 17 '22 07:10

greengreyblue