简体   繁体   中英

Spring-batch job randomly throws different exit statuses among FAILED and COMPLETED

Here are the configurations of a spring-batch project.

build.gradle:

apply plugin: 'java'

repositories {
    jcenter()
    mavenCentral()
    maven { url "http://repo.spring.io/libs-milestone" }
}

dependencies {

    // https://mvnrepository.com/artifact/org.springframework/spring-core
    compile group: 'org.springframework', name: 'spring-core', version: '5.1.3.RELEASE'

    // https://mvnrepository.com/artifact/org.springframework/spring-context
    compile group: 'org.springframework', name: 'spring-context', version: '5.1.3.RELEASE'

    // https://mvnrepository.com/artifact/org.springframework/spring-web
    compile group: 'org.springframework', name: 'spring-web', version: '5.1.3.RELEASE'

    compile group: 'org.springframework', name: 'spring-webmvc', version: '5.1.3.RELEASE'

    // https://mvnrepository.com/artifact/org.springframework.batch/spring-batch-core
    compile group: 'org.springframework.batch', name: 'spring-batch-core', version: '4.1.0.RELEASE'

    // https://mvnrepository.com/artifact/org.springframework.batch/spring-batch-infrastructure
    compile group: 'org.springframework.batch', name: 'spring-batch-infrastructure', version: '4.1.0.RELEASE'

    // https://mvnrepository.com/artifact/org.springframework.batch/spring-batch-test
    testCompile group: 'org.springframework.batch', name: 'spring-batch-test', version: '4.1.0.RELEASE'

    // https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb
    compile group: 'org.springframework.data', name: 'spring-data-mongodb', version: '2.1.3.RELEASE'

    compile group: 'org.mongodb', name: 'mongo-java-driver', version: '3.9.1'

    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'

    // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.7'

}

Job configuration:

<batch:job id="batchUpdateJob" job-repository="jobRepository">
    <batch:step id="step1" next="step2">
        <batch:tasklet allow-start-if-complete="true">
            <batch:chunk reader=“reader1”
                writer="compositeWriter" processor=“processor1” commit-interval="10" />
        </batch:tasklet>
    </batch:step>

    <batch:step id="step2">
        <batch:tasklet allow-start-if-complete="true">
            <batch:chunk reader=“reader2”
                writer=“writer2” processor=“processor2” commit-interval="10" />
        </batch:tasklet>
    </batch:step>
</batch:job>

main() where the batch job is run:

public static void main(String[] args) {
    // Loading The Bean Definition From The Spring Configuration File
    contextObj = new ClassPathXmlApplicationContext(springConfig);
    jobObj = (Job) contextObj.getBean(JOB_NAME);
    jobLauncherObj = (JobLauncher) contextObj.getBean(JOB_LAUNCHER_NAME);
    try {
        JobParametersBuilder jobBuilder = new JobParametersBuilder();
        JobExecution execution = jobLauncherObj.run(jobObj, jobParameters);
        System.out.println("Exit Status : " + execution.getStatus());
    } catch (Exception exceptionObj) {
        exceptionObj.printStackTrace();
    }
    System.out.println("Done");
}

For each run of the main(), the exitStatus of the job executed is either COMPLETED or FAILED , though no change to the project is made in between the runs.

And when the exit status is FAILED , the stepExecutions has the following trace:

[StepExecution: id=1, version=2, name=step1, status=FAILED, exitStatus=FAILED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=0, rollbackCount=0, exitDescription=org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.reader1' defined in class path resource [spring/batch/jobs/spring-beans.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:584) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:356) at org.springframework.batch.core.scope.StepScope.get(StepScope.java:113) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:353) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource .java:35) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:193) at com.sun.proxy.$Proxy18.open(Unknown Source) at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103) at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311) at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200) at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:136) at org.springframework.batch.core.job.Abstr actJob.execute(AbstractJob.java:313) at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:144) at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:137) at com.simba.tool.cacheserver.batchprocess.App.main(App.java:39) Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590) at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604) at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:219) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1697) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1653) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.ja va:1400) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575) ... 22 more Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:299) at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:585) ... 28 more ]

Bean defining both the readers are configured like this:

    <bean id="reader"
        class="org.springframework.batch.item.data.MongoItemReader" scope="step">
        <property name="template" ref="mongoTemplate" />
        <property name="collection" value="Collection" />
        <property name="targetType" value="com.example.SomeObject" />
        <property name="query" value="{ $and : [  { 'Field1': /.*#{jobParameters['Param1']}.*/ }, { 'Field2': { $gte: ISODate('9999-12-30T00:00:00Z') } }, { 'Field3': { '$eq': 'Open' } } ] }" />
        <property name="sort">
            <util:map>
                 <entry key="Field4" value="#{T(org.springframework.data.domain.Sort.Direction).ASC}" /> 
            </util:map>
        </property>
        <property name="fields" value="{ 'Field5': 1, 'Field6': 1, 'Field7': 1 }" />
    </bean>

Previous research:

My search on the exception message: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query' did not fetch any relevant results. The research using keywords like the ones in the title of this question did not shed much light either.

Why does the execution of the batch job fail sometimes and finish other times? What is the fix for this?


Update: Tried changing the definition of the readers to this:

<bean id="query" class="java.lang.String">
    <constructor-arg value="your json query here"/>
</bean>

<bean id="mongoItemReader" class="org.springframework.batch.item.data.MongoItemReader">
    <property name="query" ref="query"/>
    <!-- define other properties of the reader here -->
</bean>

Now ended up with the following trace:

[StepExecution: id=1, version=2, name=step1, status=FAILED, exitStatus=FAILED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=0, rollbackCount=0, exitDescription=org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.reader' defined in class path resource [spring/batch/jobs/spring-beans.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.sun.proxy.$Proxy19 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy19 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:584) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:356) at org.springframework.batch.core.scope.StepScope.get(StepScope.java: 113) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:353) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:193) at com.sun.proxy.$Proxy18.open(Unknown Source) at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103) at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311) at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200) at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:136) at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:313) at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:144) at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:137) at com.simba.tool.cacheserver.batchprocess.App.main(App.java:41) Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.sun.proxy.$Proxy19 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean, org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy19 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590) at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604) at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:219) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapa bleBeanFactory.java:1697) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1653) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1400) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575) ... 22 more Caused by: java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy19 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at or g.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:299) at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:585) ... 28 more ]

There are two setQuery methods in MongoItemReader : setQuery(Query) and setQuery(String) . So when configured with XML, there might be an ambiguity on which one to use. In your case, it looks like Spring is trying to convert your String query into a org.springframework.data.mongodb.core.query.Query object and it does not find a converter for that.

You need to specify which type of query to use and set it on the reader.

In your example, you need to configure the query and the reader with something like:

<bean id="query" class="java.lang.String">
    <constructor-arg value="your json query here"/>
</bean>

<bean id="mongoItemReader" class="org.springframework.batch.item.data.MongoItemReader">
    <property name="query" ref="query"/>
    <!-- define other properties of the reader here -->
</bean>

Hope this helps.

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