From 04b339b8f4bcdfd8c1763b9c7568fee09e15c603 Mon Sep 17 00:00:00 2001 From: Michael Minella Date: Tue, 16 Sep 2014 10:44:05 -0500 Subject: [PATCH] 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. --- .../repository/dao/MapStepExecutionDao.java | 2 +- .../builder/FaultTolerantStepBuilder.java | 28 ++++----- .../InteralBeanStepScopeIntegrationTests.java | 57 +++++++++++++++++++ .../JobLauncherIntegrationTests-context.xml | 3 +- .../AsyncJobScopeIntegrationTests-context.xml | 7 +-- .../CommitIntervalJobParameter-context.xml | 42 ++++++++++++++ .../batch/item/support/ListItemWriter.java | 40 +++++++++++++ 7 files changed, 158 insertions(+), 21 deletions(-) create mode 100644 spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/InteralBeanStepScopeIntegrationTests.java create mode 100644 spring-batch-core/src/test/resources/org/springframework/batch/core/scope/context/CommitIntervalJobParameter-context.xml create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemWriter.java diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/MapStepExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/MapStepExecutionDao.java index 87ad900c4..fbfee278d 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/MapStepExecutionDao.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/MapStepExecutionDao.java @@ -62,7 +62,7 @@ public class MapStepExecutionDao implements StepExecutionDao { field.setAccessible(true); field.set(targetExecution, field.get(sourceExecution)); } - }); + }, ReflectionUtils.COPYABLE_FIELDS); } @Override diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.java index e9d608ecc..50af6e377 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.java @@ -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 extends SimpleStepBuilder { 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() { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/InteralBeanStepScopeIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/InteralBeanStepScopeIntegrationTests.java new file mode 100644 index 000000000..c9b2ee437 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/context/InteralBeanStepScopeIntegrationTests.java @@ -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()); + } +} diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/JobLauncherIntegrationTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/JobLauncherIntegrationTests-context.xml index 4e0afe332..fb3d2318f 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/JobLauncherIntegrationTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/JobLauncherIntegrationTests-context.xml @@ -1,8 +1,7 @@ diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/AsyncJobScopeIntegrationTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/AsyncJobScopeIntegrationTests-context.xml index 9b88a4e42..6186cdc87 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/AsyncJobScopeIntegrationTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/AsyncJobScopeIntegrationTests-context.xml @@ -1,11 +1,8 @@ + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/context/CommitIntervalJobParameter-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/context/CommitIntervalJobParameter-context.xml new file mode 100644 index 000000000..113784000 --- /dev/null +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/context/CommitIntervalJobParameter-context.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + foo + bar + + + + + + + + + \ No newline at end of file diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemWriter.java new file mode 100644 index 000000000..cebc86c58 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemWriter.java @@ -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 implements ItemWriter { + + private List writtenItems = new ArrayList(); + + @Override + public void write(List items) throws Exception { + for (T item : items) { + writtenItems.add(item); + } + } + + public List getWrittenItems() { + return this.writtenItems; + } +}