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"
и все должно работать нормально.