Springbatch Failed to execute CommandLineRunner报错解决

本文详细解析了Spring Batch中重复执行job导致的“Failed to execute CommandLineRunner”错误,阐述了错误产生的原因,提供了通过修改参数或禁用默认job执行的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Springbatch Failed to execute CommandLineRunner报错解决

java.lang.IllegalStateException: Failed to execute CommandLineRunner
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:816) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:797) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:324) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
	at hoperun.pagoda.batchprocessingdata.BatchprocessingdataApplication.main(BatchprocessingdataApplication.java:31) [classes/:na]
Caused by: org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: A job instance already exists and is complete for parameters={-spring.output.ansi.enabled=always}.  If you want to run this job again, change the parameters.
	at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:132) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_201]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_201]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_201]
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.java:181) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]
	at com.sun.proxy.$Proxy64.createJobExecution(Unknown Source) ~[na:na]
	at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:134) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
	at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:214) ~[spring-boot-autoconfigure-2.1.4.RELEASE.jar:2.1.4.RELEASE]
	at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:186) ~[spring-boot-autoconfigure-2.1.4.RELEASE.jar:2.1.4.RELEASE]
	at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:172) ~[spring-boot-autoconfigure-2.1.4.RELEASE.jar:2.1.4.RELEASE]
	at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:166) ~[spring-boot-autoconfigure-2.1.4.RELEASE.jar:2.1.4.RELEASE]
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:813) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
	... 5 common frames omitted

springbatch 第二次启动报

Failed to execute CommandLineRunner   --执行CommandLineRunner失败

A job instance already exists and is complete for parameters={-spring.output.ansi.enabled=always}.  If you want to run this job again, change the parameters.

--job实例已经存在,并且完成了参数={-spring.output.ansi.enabled=always}。如果您想再次运行此job,请更改参数

看看代码:

package hoperun.pagoda.batchprocessingdata;

import java.util.Date;

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan
@EnableAutoConfiguration
public class BatchprocessingdataApplication {
    public static void main(String[] args) {
        //        String jobName = args[0];
        String jobName = "userMigrationJob0";
        try {
            //System.out.println("节点1");
            ConfigurableApplicationContext context = SpringApplication.run(BatchprocessingdataApplication.class, args);
            JobRegistry jobRegistry = context.getBean(JobRegistry.class);
            Job job = jobRegistry.getJob(jobName);
            JobLauncher jobLauncher = context.getBean(JobLauncher.class);
            //System.out.println("节点2:");
            JobExecution jobExecution = jobLauncher.run(job, createJobParams());
            if (!jobExecution.getExitStatus().equals(ExitStatus.COMPLETED)) {
                throw new RuntimeException(jobName +" Job execution failed.");
            }
        } catch (Exception e) {
            throw new RuntimeException(jobName +" Job execution failed.");
        }
    }

    private static JobParameters createJobParams() {
        //System.out.println("节点3");
        return new JobParametersBuilder().addDate("date", new Date()).toJobParameters();
    }
}

我明明设置了return new JobParametersBuilder().addDate("date", new Date()).toJobParameters();

这里的.addDate("date", new Date()) 明明每次参数不一样!!!但为啥还报参数一样呢!!!

解决办法:

在application.properties中增加配置:

spring.batch.job.enabled=false

把job都设置成不可用,程序便会根据jobLauncher.run来执行job。

 

产生错误原因:

因为spring batch在加载的时候每个job默认都会执行,默认先去执行job 库里面判断已经有这个job并且执行成了则报错,

--这是没有设置spring.batch.job.enabled=false时的打印

--这是设置了spring.batch.job.enabled=false时的打印

### 关于 `Failed to execute ApplicationRunner` 报错的原因及解决方案 #### 1. **报错原因** 该异常通常发生在 Spring Boot 启动过程中,当实现了 `ApplicationRunner` 接口的 Bean 执行其 `run` 方法时发生错误。具体可能由以下几个方面引起: - **依赖服务未启动** 如果当前微服务依赖其他外部服务(如 Elasticsearch、数据库等),而这些服务尚未准备好,则可能导致运行失败[^3]。 - **参数配置问题** 配置文件中的某些参数设置不当,例如 ES 的版本不匹配、端口号错误或集群名称不符等问题均会引发此异常[^4]。 - **逻辑错误** 在 `ApplicationRunner.run()` 方法内部可能存在编码缺陷,比如尝试访问不存在的对象或者执行非法操作等[^2]。 - **重复作业实例** 对于使用 Spring Batch 的场景来说,如果试图以相同的参数重新提交已完成的任务也会抛出此类状态异常[^5]。 #### 2. **解决办法** 以下是几种常见的排查与修复策略: - **确认外部资源可用性** 检查所有必要的第三方组件是否已经成功初始化并处于可工作状态。对于案例提到的 ElasticSearch ,不仅要验证其本身的服务状况良好,还需确保索引结构满足预期需求。若有缺失则需补充创建相应索引。 - **校验环境变量一致性** 细致对比生产环境中实际使用的各项属性值同开发测试阶段设定之间是否存在差异,并调整至统一标准[^4]。 - **优化业务流程代码质量** 审视涉及 `ApplicationRunner` 实现部分的具体实现细节,修正其中潜在的风险点。例如,在删除请求前加入条件判断来规避空指针风险: ```java if (indexExists(indexName)) { DeleteByQueryRequest queryRequest = new DeleteByQueryRequest(indexName); // 进一步处理... } ``` - **管理批次任务唯一性约束** 若应用程序集成了批处理框架,则应考虑引入额外标识符作为区分不同运行周期依据之一,从而避免因违反唯一键规则而导致冲突情形的发生[^5]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值