简体   繁体   中英

Spring Boot batch plus scheduler

I am new to spring batch so trying to schedule a batch works as a job every 5 seconds using spring boot batch and scheduler but somewhere I am missing something so getting below error.Please help me to solve this error.

Error:-

2017-03-12 02:23:26.614  INFO 8292 --- [pool-1-thread-1] com.spring.test.BatchConfig              : The time is now 02:23:26
2017-03-12 02:23:26.617 ERROR 8292 --- [pool-1-thread-1] o.s.s.s.TaskUtils$LoggingErrorHandler    : Unexpected error occurred in scheduled task.

java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
    at org.springframework.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.enhanceFactoryBean(ConfigurationClassEnhancer.java:384)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:292)
    at com.spring.test.BatchConfig$$EnhancerBySpringCGLIB$$dcfce226.job(<generated>)
    at com.spring.test.BatchConfig.reportCurrentTime(BatchConfig.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

application.properties:-

spring.batch.job.enabled=false

spring-config.xml:-

<beans:beans xmlns="http://www.springframework.org/schema/batch"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/batch
           http://www.springframework.org/schema/batch/spring-batch-3.0.xsd">



    <job id="job">
        <step id="step1">
            <tasklet>
                <chunk reader="itemReader" processor="itemProcessor" writer="itemWriter"
                    commit-interval="1" />
            </tasklet>
        </step>
    </job>

    <beans:bean id="itemReader" class="com.spring.test.Reader" />
    <beans:bean id="itemProcessor" class="com.spring.test.Processor" />
    <beans:bean id="itemWriter" class="com.spring.test.Writer" />

</beans:beans>

Application:-

@SpringBootApplication
@EnableScheduling
@ComponentScan
@ImportResource("classpath:spring-config.xml")
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class);
    }
}

BatchConfig:-

@Configuration
@EnableBatchProcessing
@Import({BatchScheduler.class})
public class BatchConfig {

    private static final Logger log = LoggerFactory
            .getLogger(BatchConfig.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat(
            "HH:mm:ss");

    @Autowired
    private SimpleJobLauncher jobLauncher;

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job job() {
        return jobBuilderFactory.get("job")
                .incrementer(new RunIdIncrementer())
                .flow(step1())
                .end()
                .build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<String, String> chunk(1)
                .reader(new Reader())
                .processor(new Processor())
                .writer(new Writer())
                .build();
    }

    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() throws Exception{
        log.info("The time is now {}", dateFormat.format(new Date()));
        JobParameters param = new JobParametersBuilder().addString("JobID",
                String.valueOf(System.currentTimeMillis())).toJobParameters();
        JobExecution execution =  jobLauncher.run(job(), param);
        System.out.println("Job Execution Status: " + execution.getStatus());
    }


}

BatchScheduler:-

@Configuration
@EnableScheduling
public class BatchScheduler {

    @Bean
    public ResourcelessTransactionManager transactionManager() {
        return new ResourcelessTransactionManager();
    }

    @Bean
    public MapJobRepositoryFactoryBean mapJobRepositoryFactory(
            ResourcelessTransactionManager txManager) throws Exception {

        MapJobRepositoryFactoryBean factory = new 
                MapJobRepositoryFactoryBean(txManager);

        factory.afterPropertiesSet();

        return factory;
    }

    @Bean
    public JobRepository jobRepository(
            MapJobRepositoryFactoryBean factory) throws Exception {
        return factory.getObject();
    }

    @Bean
    public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
        SimpleJobLauncher launcher = new SimpleJobLauncher();
        launcher.setJobRepository(jobRepository);
        return launcher;
    }

}

It is hard to figure out what is actually wrong with your code but it looks like some of your beans do not have no-args constructor.

Configuring batch with scheduler is relatively simple. I've just downloaded the code from official batch guide and extended it with small amount of my own code.

You can try the same:

1) Add spring.batch.job.enabled=false to application.properties file (just like you already have in your project)

2) Add @EnableScheduling to a Application class (just like you have in your code)

3) Create a Component class for scheduling with the next code:

import org.springframework.batch.core.*;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class Scheduler {
    @Autowired
    private JobLauncher jobLauncher;
    @Autowired
    private Job job;

    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() throws Exception{
        JobParameters param = new JobParametersBuilder().addString("JobID",
                String.valueOf(System.currentTimeMillis())).toJobParameters();
        JobExecution execution =  jobLauncher.run(job, param);
        System.out.println("Job Execution Status: " + execution.getStatus());
    }
}

That works well. Hope that having this example you'll figure out what is wrong with your own code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM