当使用modular = true配置时,作业在SpringBatch中调用两次

我正在尝试使用Spring Batch进行工作 . 我在两个独立的配置中有两个作业tempJob和tempJob2 . 当尝试使用命令行参数(-Dspring.batch.job.names = tempJob)运行tempJob时,SpringBatch尝试运行tempJob两次,我得到以下错误

2018-06-15 11:36:37.956 INFO 14436 --- [main] osbclsupport.SimpleJobLauncher:Job:[SimpleJob:[name = tempJob]]使用以下参数完成:[{TimeStamp = 06152018 11:36: 30}]和以下状态:[已完成] 2018-06-15 11:36:38.049 INFO 14436 --- [main] ConditionEvaluationReportLoggingListener:启动ApplicationContext时出错 . 要显示条件报告,请在启用“debug”的情况下重新运行应用程序 . 2018-06-15 11:36:38.058 ERROR 14436 --- [main] osboot.SpringApplication:应用程序运行失败java.lang.IllegalStateException:无法在org.springframework.boot.SpringApplication.callRunner(SpringApplication.java)上执行CommandLineRunner :800)[org.springframework.boot.SpringApplication.callRunners上的[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE](SpringApplication.java:781)[spring-boot-2.0.3.RELEASE . jar:2.0.3.RELEASE]在org.springframework.boot上的org.springframework.boot.SpringApplication.run(SpringApplication.java:335)[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] .SpringApplication.run(SpringApplication.java:1255)[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]在org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)[spring- com.example.springbatchdemo.SpringbatchdemoApplication.main中的boot-2.0.3.RELEASE.jar:2.0.3.RELEASE](classes /:na)引起:org.springframework.batch.core . repository.JobInstanceAlreadyCompleteEx ception:作业实例已经存在,并且参数完成= {TimeStamp = 06152018 11:36:30} . 如果要再次运行此作业,请更改参数 . 在sun.reflect的org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:130)〜[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE] . NativeMethodAccessorImpl.invoke0(Native Method)〜[na:1.8.0_60] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)〜[na:1.8.0_60] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java :43)〜[na:1.8.0_60] at java.lang.reflect.Method.invoke(Method.java:497)〜[na:1.8.0_60] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils .java:343)〜[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE] org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197)〜[spring-aop- 5.0.7.RELEASE.jar:5.0.7.RELEASE]在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)〜[spring-aop-5.0.7.RELEASE.jar:5.0.7 .RELEASE] org.springframework org.springframework.transaction.interceptor.TransactionInterceptor.invoke中的.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)〜[spring-tx-5.0.7.RELEASE.jar:5.0.7.RELEASE](TransactionInterceptor . java:98)〜[spring-tx-5.0.7.RELEASE.jar:5.0.7.RELEASE] org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)〜[spring-aop-5.0 .7.RELEASE.jar:5.0.7.RELEASE]在org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean $ 1.invoke(AbstractJobRepositoryFactoryBean.java:181)〜[spring-batch-core-4.0.1.RELEASE .jar:4.0.1.RELEASE]在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)〜[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org .springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)〜[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE] at com.sun.proxy . $ Proxy48.createJobExecution(Unknown)来源)〜[na:na] at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:131)〜[spring-batch-core-4.0.1.RELEASE.jar:4.0.1 .RELEASE] org.springframework上的org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:163)〜[spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE] .boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeRegisteredJobs(JobLauncherCommandLineRunner.java:148)〜[spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE] atorg.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:135)〜[spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE] org.springframework.boot.autoconfigure orb.springframework.boot.SpringApplication.callRunner中的.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:128)〜[spring-boot-autoconfigure-2.0.3.RELEASE.jar:2.0.3.RELEASE](SpringApplication.java: 797)[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] ...省略了5个常用帧2018-06-15 11:36:38.060 INFO 14436 --- [main] scaAnnotationConfigApplicationContext:关闭org.springframework.context.annotation.AnnotationConfigApplicationContext@770c2e6b:启动日期[Fri Jun 15 11:36:31 EDT 2018];上下文层次结构2018-06-15 11:36:38.061 INFO 14436 --- [main] oscsupport.DefaultLifecycleProcessor:在阶段-2147482648停止bean 2018-06-15 11:36:38.062 INFO 14436 --- [main ] ory $ ResourceAnnotationApplicationContext:关闭ResourceAnnotationApplicationContext:com.example.springbatchdemo.config.TempConfig 2018-06-15 11:36:38.063 INFO 14436 --- [main] ory $ ResourceAnnotationApplicationContext:关闭ResourceAnnotationApplicationContext:com.example.springbatchdemo.config . TempConfig2 2018-06-15 11:36:38.064 INFO 14436 --- [main] osjeaAnnotationMBeanExporter:在关闭时取消注册JMX暴露的bean 2018-06-15 11:36:38.065 INFO 14436 --- [main] osjeaAnnotationMBeanExporter:取消注册JMX暴露的bean 2018-06-15 11:36:38.065 INFO 14436 --- [main] com.zaxxer.hikari.HikariDataSource:HikariPool-1 - Shutdown发起... 2018-06-15 11:36:38.098 INFO 14436 --- [main] com.zaxxer.hikari.HikariDataSource:HikariPool-1 - 关闭完成 .

以下是我的Spring Batch配置这是我的主要课程

@SpringBootApplication
@EnableBatchProcessing(modular=true)
public class SpringbatchdemoApplication {

    public static void main(String[] args) {
        String[] params = addTimestampAsParameter(args);
        SpringApplication.run(SpringbatchdemoApplication.class, params);
    }

     @Bean
     public ApplicationContextFactory runTempJob1() {
        return new GenericApplicationContextFactory(TempConfig.class);
     }

     @Bean
     public ApplicationContextFactory runTempJob2() {
        return new GenericApplicationContextFactory(TempConfig2.class);
     }


    public static String[] addTimestampAsParameter(final String[] args){
        String[] params = null;
        if(null != args){
            params = new String[args.length+1];
            for(int i=0;i<args.length;i++){
                params[i]=args[i];
            }
        }else{
            params = new String[1];
        }
        SimpleDateFormat sdf = new SimpleDateFormat("MMddyyyy hh:mm:ss");
        String timeStamp = sdf.format(new Date());
        params[params.length-1] = String.format("TimeStamp=%s", timeStamp);
        return params;
    }
}

以下是我的配置类

@Configuration
public class TempConfig {

    @Autowired
    JobBuilderFactory jobBuilder;

    @Autowired
    StepBuilderFactory stepBuilder;

    @Bean
    public Tasklet sampleTask(){
        return new Tasklet() {

            @Override
            public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception {
                System.out.println("Executed Temp Step of TempConfig Job -> TempJob");
                return RepeatStatus.FINISHED;
            }
        };
    }

    @Bean
    public Step tempStep(Tasklet sampleTask){
        return stepBuilder.get("tempStep").tasklet(sampleTask).build();
    }

    @Bean
    public Job tempJob(){
        return jobBuilder.get("tempJob")
        .start(tempStep(null))
        .build();
    }

}

和第二个作业配置

@Configuration
    public class TempConfig2 {

        @Autowired
        JobBuilderFactory jobBuilder;

        @Autowired
        StepBuilderFactory stepBuilder;
        @Bean
        public Step tempStep1(){
            return stepBuilder.get("tempStep1").tasklet(new Tasklet() {

                @Override
                public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception {
                    System.out.println("Executed Temp Step of TempConfig2 Job -> TempJob1");
                    return RepeatStatus.FINISHED;
                }
            }).build();
        }

        @Bean
        public Job tempJob1(){
            return jobBuilder.get("tempJob1")
            .start(tempStep1())
            .build();
        }

    }

当我进一步研究时,我发现,在给出-Dspring.batch.job.names时,SpringBatch使用JobLauncherCommandLineRunner.launchJobFromProperties()方法来执行作业 . 此方法尝试使用executeLocalJobs(jobParameters)和executeRegisteredJobs(jobParameters)执行作业;在调试时,我发现我的工作正由两种方法执行 .

是否有任何解决方案只使用命令行参数(modular = true)运行一次作业 . 如果您需要更多信息,请提供帮助并告知 .

回答(0)