Add BeanCreationException to list of standard failure exceptions

Without this change, when passing an invalid job parameter to a bean
that is created internally by Spring Batch will cause a
BeanCreationException that is essentially ignored.  Due to it being
ignored, an infinite loop occurs in processing.
This commit is contained in:
Michael Minella
2014-09-16 10:44:05 -05:00
parent 1e54018df3
commit 04b339b8f4
7 changed files with 158 additions and 21 deletions

View File

@@ -62,7 +62,7 @@ public class MapStepExecutionDao implements StepExecutionDao {
field.setAccessible(true);
field.set(targetExecution, field.get(sourceExecution));
}
});
}, ReflectionUtils.COPYABLE_FIELDS);
}
@Override

View File

@@ -15,6 +15,18 @@
*/
package org.springframework.batch.core.step.builder;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.batch.operations.BatchRuntimeException;
import org.springframework.batch.core.ChunkListener;
import org.springframework.batch.core.JobInterruptedException;
import org.springframework.batch.core.SkipListener;
@@ -55,6 +67,7 @@ import org.springframework.batch.item.ItemStream;
import org.springframework.batch.repeat.RepeatOperations;
import org.springframework.batch.repeat.support.RepeatTemplate;
import org.springframework.batch.support.ReflectionUtils;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.classify.BinaryExceptionClassifier;
import org.springframework.classify.Classifier;
import org.springframework.classify.SubclassClassifier;
@@ -73,17 +86,6 @@ import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.util.Assert;
import javax.batch.operations.BatchRuntimeException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A step builder for fully fault tolerant chunk-oriented item processing steps. Extends {@link SimpleStepBuilder} with
* additional properties for retry and skip of failed items.
@@ -488,11 +490,11 @@ public class FaultTolerantStepBuilder<I, O> extends SimpleStepBuilder<I, O> {
private void addSpecialExceptions() {
addNonSkippableExceptionIfMissing(SkipLimitExceededException.class, NonSkippableReadException.class,
SkipListenerFailedException.class, SkipPolicyFailedException.class, RetryException.class,
JobInterruptedException.class, Error.class);
JobInterruptedException.class, Error.class, BeanCreationException.class);
addNonRetryableExceptionIfMissing(SkipLimitExceededException.class, NonSkippableReadException.class,
TransactionException.class, FatalStepExecutionException.class, SkipListenerFailedException.class,
SkipPolicyFailedException.class, RetryException.class, JobInterruptedException.class, Error.class,
BatchRuntimeException.class);
BatchRuntimeException.class, BeanCreationException.class);
}
protected void detectStreamInReader() {

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.scope.context;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import static org.junit.Assert.assertEquals;
/**
* @author mminella
*/
public class InteralBeanStepScopeIntegrationTests {
@Test
public void testCommitIntervalJobParameter() throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("/org/springframework/batch/core/scope/context/CommitIntervalJobParameter-context.xml");
Job job = context.getBean(Job.class);
JobLauncher launcher = context.getBean(JobLauncher.class);
JobExecution execution = launcher.run(job, new JobParametersBuilder().addLong("commit.interval", 1l).toJobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(2, execution.getStepExecutions().iterator().next().getReadCount());
assertEquals(2, execution.getStepExecutions().iterator().next().getWriteCount());
}
@Test
public void testInvalidCommitIntervalJobParameter() throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("/org/springframework/batch/core/scope/context/CommitIntervalJobParameter-context.xml");
Job job = context.getBean(Job.class);
JobLauncher launcher = context.getBean(JobLauncher.class);
JobExecution execution = launcher.run(job, new JobParametersBuilder().addLong("commit.intervall", 1l).toJobParameters());
assertEquals(BatchStatus.FAILED, execution.getStatus());
}
}

View File

@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:batch="http://www.springframework.org/schema/batch"
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<job id="job" xmlns="http://www.springframework.org/schema/batch">

View File

@@ -1,11 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="simple" class="org.springframework.batch.core.scope.TestCollaborator" scope="job">
<property name="name" value="#{jobExecutionContext[foo]}" />

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<job id="basicSkipJob"
xmlns="http://www.springframework.org/schema/batch">
<step id="basicSkipStep" >
<tasklet>
<chunk
reader="reader"
writer="writer"
commit-interval="#{jobParameters['commit.interval']}"
skip-policy="skipPolicy">
</chunk>
</tasklet>
</step>
</job>
<bean id="reader" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>foo</value>
<value>bar</value>
</list>
</constructor-arg>
</bean>
<bean id="writer" class="org.springframework.batch.item.support.ListItemWriter"/>
<bean id="skipPolicy" class="org.springframework.batch.core.step.skip.AlwaysSkipItemSkipPolicy"/>
</beans>

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.support;
import org.springframework.batch.item.ItemWriter;
import java.util.ArrayList;
import java.util.List;
/**
* @author mminella
*/
public class ListItemWriter<T> implements ItemWriter<T> {
private List<T> writtenItems = new ArrayList<T>();
@Override
public void write(List<? extends T> items) throws Exception {
for (T item : items) {
writtenItems.add(item);
}
}
public List<? extends T> getWrittenItems() {
return this.writtenItems;
}
}