春季批处理作业在FAILED和COMPLETED中随机抛出不同的退出状态

时间:2018-12-24 11:36:13

标签: java spring spring-batch

这是spring-batch项目的配置。

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'

}

作业配置:

<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():

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");
}

对于main()的每次运行,执行的作业的exitStatusCOMPLETEDFAILED,尽管在两次运行之间没有对项目进行任何更改。 / p>

并且当退出状态为FAILED时,stepExecutions具有以下跟踪:

  

[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:创建在类路径资源[spring / batch / jobs / spring-beans.xml]中定义的名称为'scopedTarget.reader1'的bean时出错。豆失败;嵌套异常是org.springframework.beans.ConversionNotSupportedException:无法将类型“ java.lang.String”的属性值转换为属性“ query”所需的类型“ org.springframework.data.mongodb.core.query.Query”;嵌套异常为java.lang.IllegalStateException:无法将属性“ query”的类型“ java.lang.String”的值转换为所需的类型“ org.springframework.data.mongodb.core.query.Query”:没有匹配的编辑器或转换找到策略          在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:584)          在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)处          在org.springframework.beans.factory.support.AbstractBeanFactory.lambda $ doGetBean $ 1(AbstractBeanFactory.java:356)          在org.springframework.batch.core.scope.StepScope.get(StepScope.java:113)          在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:353)          在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)          在org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)          在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:193)          在com.sun.proxy。$ Proxy18.open(未知来源)          在org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)          在org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311)          在org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200)          在org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)          在org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68)          在org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67)          在org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169)          在org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144)          在org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:136)          在org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:313)          在org.springframework.batch.core.launch.support.SimpleJobLauncher $ 1.run(SimpleJobLauncher.java:144)          在org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)          在org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:137)          在com.simba.tool.cacheserver.batchprocess.App.main(App.java:39)       原因:org.springframework.beans.ConversionNotSupportedException:无法将类型“ java.lang.String”的属性值转换为属性“ query”所需的类型“ org.springframework.data.mongodb.core.query.Query”;嵌套异常为java.lang.IllegalStateException:无法将属性“ query”的类型“ java.lang.String”的值转换为所需的类型“ org.springframework.data.mongodb.core.query.Query”:没有匹配的编辑器或转换找到策略          在org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590)          在org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604)          在org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:219)          在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1697)          在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1653)          在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1400)          在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575)          ...另外22个       原因:java.lang.IllegalStateException:无法将属性“ query”的类型“ java.lang.String”的值转换为所需的类型“ org.springframework.data.mongodb.core.query.Query”:没有匹配的编辑器或转换找到策略          在org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:299)          在org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:585)          ...另外28个       ]

定义两个阅读器的Bean的配置如下:

    <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>

先前的研究:

我对异常消息Cannot convert value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query’的搜索未获取任何相关结果。 使用诸如该问题标题中的关键字之类的关键字进行的研究也未引起太多关注。

为什么批处理作业的执行有时会失败,而另一些时候会结束?解决的办法是什么?


更新: 尝试将读者的定义更改为此:

<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>

现在结束了以下跟踪:

  

[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:在类路径资源[spring / batch / jobs / spring-beans.xml]中创建名称为“ scopedTarget.reader”的bean时出错。豆失败;嵌套异常是org.springframework.beans.ConversionNotSupportedException:无法转换类型为'com.sun.proxy。$ Proxy19的属性值,实现了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。建议,org.springframework.core.DecoratingProxy'为必需的类型'org.springframework。 data.mongodb.core.query.Query'属性'query';嵌套异常是java.lang.IllegalStateException:无法转换实现java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope的'com.sun.proxy。$ Proxy19类型的值。 ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.advised,org.springframework.core.DecoratingProxy'为必需的类型'org.springframework.data.mongodb。属性'query'的core.query.Query':找不到匹配的编辑器或转换策略           在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:584)           在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)处           在org.springframework.beans.factory.support.AbstractBeanFactory.lambda $ doGetBean $ 1(AbstractBeanFactory.java:356)           在org.springframework.batch.core.scope.StepScope.get(StepScope.java:113)           在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:353)           在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)           在org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)           在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:193)           在com.sun.proxy。$ Proxy18.open(未知来源)           在org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103)           在org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311)           在org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200)           在org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)           在org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68)           在org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67)           在org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169)           在org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144)           在org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:136)           在org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:313)           在org.springframework.batch.core.launch.support.SimpleJobLauncher $ 1.run(SimpleJobLauncher.java:144)           在org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)           在org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:137)           在com.simba.tool.cacheserver.batchprocess.App.main(App.java:41)       引起原因:org.springframework.beans.ConversionNotSupportedException:无法转换实现java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework的'com.sun.proxy。$ Proxy19类型的属性值。 aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework。建议,org.springframework.core.DecoratingProxy'为必需的类型'org.springframework。 data.mongodb.core.query.Query'属性'query';嵌套异常是java.lang.IllegalStateException:无法转换实现java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope的'com.sun.proxy。$ Proxy19类型的值。 ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.advised,org.springframework.core.DecoratingProxy'为必需的类型'org.springframework.data.mongodb。属性'query'的core.query.Query':找不到匹配的编辑器或转换策略           在org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590)           在org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604)           在org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:219)           在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1697)           在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1653)           在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1400)           在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575)           ...另外22个       引起原因:java.lang.IllegalStateException:无法转换实现java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope的'com.sun.proxy。$ Proxy19类型的值。 ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.advised,org.springframework.core.DecoratingProxy'为必需的类型'org.springframework.data.mongodb。属性'query'的core.query.Query':找不到匹配的编辑器或转换策略           在org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:299)           在org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:585)           ...另外28个       ]

1 个答案:

答案 0 :(得分:1)

setQuery中有两种MongoItemReader方法:setQuery(Query)setQuery(String)。因此,在配置XML时,可能会使用哪种歧义。在您的情况下,Spring似乎试图将您的String查询转换为org.springframework.data.mongodb.core.query.Query对象,但找不到该对象的转换器。

您需要指定要使用的查询类型,并在阅读器上进行设置。

在您的示例中,您需要使用以下方式配置查询和阅读器:

<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>

希望这会有所帮助。