Spring Batch IllegalArgumentException при выполнении шага с чанком за шагом с помощью тасклета

У меня есть сценарий, где первый шаг - проверка схемы XML, я использовал тасклет для проверки XML по схеме, используя ref="beanId", обратите внимание, что здесь не обрабатывается никакой чанк. Следующий шаг с чанком, то есть конфигурацией считывателя, процессора и записывающего устройства. Я получаю исключение IllegalArgument, если я выполняю тасклет проверки схемы и далее. "NextStep" с чанком. Исключением является то, что Step [nextStep] имеет как элемент, так и атрибут ref, ссылающийся на тасклет. Определение 'nextStep' имеет чанк, но не элемент ref. Полный код ниже.

Случай 1 - если задание выполняется с приведенной ниже конфигурацией, оно работает нормально, но мне нужно обработать данные в xml после проверки схемы. Случай 2 - ошибочный сценарий. Не уверен, что происходит не так. Разве это не допустимо в весенней партии для выполнения шага с чаком после шага тасклета?

<batch:job id="DataEnhancement" job-repository="jobRepository">
        <!-- 1. Validate Input file against schema, if validation fails, notify 
            error -->
        <batch:step id="validateSchema">
            <tasklet ref="SchemaValidatorTasklet" transaction-manager="hibernateTransactionManager"/>
            <batch:end on="*" />
            <batch:next on="FAILED" to="generateErrorResponseXml" />
        </batch:step>

        <!-- 9. Generate response xml for schema validation failure.  -->
        <batch:step id="generateErrorResponseXml" parent="validateSchema">
            <tasklet ref="schemaValidationErrorXmlTasklet"
                allow-start-if-complete="true" />
            <batch:next on="*" to="notifyError" />
        </batch:step>

        <!-- 10. Error notification tasklet to notify error. TODO : No requirements 
            on error notifications -->
        <batch:step id="notifyError">
            <tasklet ref="notifyFailureTasklet" allow-start-if-complete="true" />
            <batch:fail on="*" exit-code="FAILED" />
        </batch:step>
    </batch:job>

Case 2 - I have added readHeader step after validateSchema step, modified configuration is as below.
    <batch:job id="DataEnhancement" job-repository="jobRepository">
        <!-- 1. Validate Input file against schema, if validation fails, notify 
            error -->
        <batch:step id="validateSchema">
            <tasklet ref="SchemaValidatorTasklet" transaction-manager="hibernateTransactionManager"/>
            <!-- <batch:end on="*" /> -->
            <batch:next on="*" to="readHeader" />
            <batch:next on="FAILED" to="generateErrorResponseXml" />
        </batch:step>

        <!-- 2. Read PDE header details and persist into stage tables -->
        <batch:step id="readHeader" parent="validateSchema">
            <batch:tasklet transaction-manager="hibernateTransactionManager">
                <batch:chunk reader="xmlHeaderReader" processor="HeaderProcessor"
                    writer="hibernateItemWriter" commit-interval="1" />
            </batch:tasklet>
            <batch:end on="*" />
            <!-- <batch:next on="*" to="readPdeTrailer" /> -->
            <batch:next on="FAILED" to="notifyError" />
        </batch:step>

        <!-- 9. Generate response xml for schema validation failure. -->
        <batch:step id="generateErrorResponseXml" parent="validateSchema">
            <tasklet ref="schemaValidationErrorXmlTasklet"
                allow-start-if-complete="true" />
            <batch:next on="*" to="notifyError" />
        </batch:step>

        <!-- 10. Error notification tasklet to notify error. TODO : No requirements 
            on error notifications -->
        <batch:step id="notifyError">
            <tasklet ref="notifyFailureTasklet" allow-start-if-complete="true" />
            <batch:fail on="*" exit-code="FAILED" />
        </batch:step>
    </batch:job>

Получение следующей трассировки стека

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DataEnhancement': Cannot create inner bean '(inner bean)#47634763' of type [org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean] while setting bean property 'flow'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#47634763': Cannot create inner bean '(inner bean)#27b627b6' of type [org.springframework.batch.core.job.flow.support.StateTransition] while setting bean property 'stateTransitions' with key [2]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#27b627b6': Cannot create inner bean '(inner bean)#7d267d26' of type [org.springframework.batch.core.job.flow.support.state.StepState] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#7d267d26': Cannot resolve reference to bean 'readHeader' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'readHeader': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Step [readHeader] has both a <chunk/> element and a 'ref' attribute  referencing a Tasklet.
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:290)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:684)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
    at com.batch.app.XmlReadHibernateWriteBatchApplication.main(XmlReadHibernateWriteBatchApplication.java:36)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#47634763': Cannot create inner bean '(inner bean)#27b627b6' of type [org.springframework.batch.core.job.flow.support.StateTransition] while setting bean property 'stateTransitions' with key [2]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#27b627b6': Cannot create inner bean '(inner bean)#7d267d26' of type [org.springframework.batch.core.job.flow.support.state.StepState] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#7d267d26': Cannot resolve reference to bean 'readHeader' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'readHeader': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Step [readHeader] has both a <chunk/> element and a 'ref' attribute  referencing a Tasklet.
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:290)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:359)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:157)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:276)
    ... 15 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#27b627b6': Cannot create inner bean '(inner bean)#7d267d26' of type [org.springframework.batch.core.job.flow.support.state.StepState] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#7d267d26': Cannot resolve reference to bean 'readHeader' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'readHeader': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Step [readHeader] has both a <chunk/> element and a 'ref' attribute  referencing a Tasklet.
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:290)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:632)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:442)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:276)
    ... 23 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#7d267d26': Cannot resolve reference to bean 'readHeader' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'readHeader': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Step [readHeader] has both a <chunk/> element and a 'ref' attribute  referencing a Tasklet.
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:336)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:632)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:140)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1114)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1017)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:276)
    ... 31 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'readHeader': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Step [readHeader] has both a <chunk/> element and a 'ref' attribute  referencing a Tasklet.
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:175)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1512)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:250)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    ... 39 more
Caused by: java.lang.IllegalArgumentException: Step [readHeader] has both a <chunk/> element and a 'ref' attribute  referencing a Tasklet.
    at org.springframework.util.Assert.isNull(Assert.java:89)
    at org.springframework.batch.core.configuration.xml.StepParserStepFactoryBean.getObject(StepParserStepFactoryBean.java:268)
    at org.springframework.batch.core.configuration.xml.StepParserStepFactoryBean.getObject(StepParserStepFactoryBean.java:113)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
    ... 44 more

1 ответ

Решение

"Чтение" вашего (неформатированного) стека отслеживает проблему здесь:

Ошибка создания бина с именем readHeader: FactoryBean выдал исключение при создании объекта; Вложенное исключение - java.lang.IllegalArgumentException: Step [readHeader] имеет как элемент, так и атрибут ref, ссылающийся на Tasklet

и проблема здесь:

<batch:step id="readHeader" parent="validateSchema">

вы наследуете шаг конфигурации validateSchema шаг, который содержит ссылку на таскет и readHeader реализует шаг на основе чанка.
Удалить parent="validateSchema" и все должно работать нормально.

Другие вопросы по тегам