Skip to content

Commit 99a3799

Browse files
committed
rework listener error handling to check annotations for different listeners in all builders. It now checks for errors on top levels before adding new ones to ensure a listener has not already been registered for the current call.
Signed-off-by: SoxerL <[email protected]>
1 parent 6e3a720 commit 99a3799

File tree

13 files changed

+77
-8
lines changed

13 files changed

+77
-8
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/FlowJobBuilder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ public Job build() {
9393
job.setName(getName());
9494
job.setFlow(flow);
9595
super.enhance(job);
96+
if (!listenerErrors.isEmpty()) {
97+
throw new JobBuilderException(
98+
new IllegalArgumentException("Errors occurred while registering listeners" + listenerErrors));
99+
}
96100
try {
97101
job.afterPropertiesSet();
98102
}

spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilderHelper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ public abstract class JobBuilderHelper<B extends JobBuilderHelper<B>> {
5454

5555
private final CommonJobProperties properties;
5656

57+
protected List<Throwable> listenerErrors = new ArrayList<>();
58+
5759
/**
5860
* Create a new {@link JobBuilderHelper}.
5961
* @param jobRepository the job repository
@@ -83,6 +85,7 @@ public JobBuilderHelper(String name, JobRepository jobRepository) {
8385
*/
8486
protected JobBuilderHelper(JobBuilderHelper<?> parent) {
8587
this.properties = new CommonJobProperties(parent.properties);
88+
this.listenerErrors = parent.listenerErrors;
8689
}
8790

8891
/**
@@ -162,7 +165,8 @@ public B listener(Object listener) {
162165
properties.addJobExecutionListener((JobExecutionListener) factory.getObject());
163166
}
164167
else {
165-
throw new IllegalArgumentException("Missing @BeforeJob or @AfterJob annotations on Listener.");
168+
listenerErrors
169+
.add(new IllegalArgumentException("Missing @BeforeJob or @AfterJob annotations on Listener."));
166170
}
167171

168172
@SuppressWarnings("unchecked")

spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/SimpleJobBuilder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public Job build() {
5353
SimpleJob job = new SimpleJob(getName());
5454
super.enhance(job);
5555
job.setSteps(steps);
56+
if (!listenerErrors.isEmpty()) {
57+
throw new JobBuilderException(
58+
new IllegalArgumentException("Errors occurred while registering listeners" + listenerErrors));
59+
}
5660
try {
5761
job.afterPropertiesSet();
5862
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ public TaskletStep build() {
107107

108108
step.setChunkListeners(chunkListeners.toArray(new ChunkListener[0]));
109109

110+
if (!listenerErrors.isEmpty()) {
111+
throw new StepBuilderException(
112+
new IllegalArgumentException("Errors occurred while registering listeners" + listenerErrors));
113+
}
114+
110115
if (this.transactionManager != null) {
111116
step.setTransactionManager(this.transactionManager);
112117
}
@@ -170,17 +175,21 @@ public B listener(ChunkListener listener) {
170175
@Override
171176
public B listener(Object listener) {
172177
super.listener(listener);
173-
174178
Set<Method> chunkListenerMethods = new HashSet<>();
175179
chunkListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), BeforeChunk.class));
176180
chunkListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), AfterChunk.class));
177181
chunkListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), AfterChunkError.class));
178182

179183
if (!chunkListenerMethods.isEmpty()) {
184+
listenerErrors.clear();
180185
StepListenerFactoryBean factory = new StepListenerFactoryBean();
181186
factory.setDelegate(listener);
182187
this.listener((ChunkListener) factory.getObject());
183188
}
189+
else if (!listenerErrors.isEmpty()) {
190+
listenerErrors.add(new IllegalArgumentException(
191+
"Missing @BeforeChunk, @AfterChunk or @AfterChunkError annotations on Listener."));
192+
}
184193

185194
return self();
186195
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,17 +194,21 @@ protected Tasklet createTasklet() {
194194
@Override
195195
public FaultTolerantStepBuilder<I, O> listener(Object listener) {
196196
super.listener(listener);
197-
198197
Set<Method> skipListenerMethods = new HashSet<>();
199198
skipListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), OnSkipInRead.class));
200199
skipListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), OnSkipInProcess.class));
201200
skipListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), OnSkipInWrite.class));
202201

203202
if (!skipListenerMethods.isEmpty()) {
203+
listenerErrors.clear();
204204
StepListenerFactoryBean factory = new StepListenerFactoryBean();
205205
factory.setDelegate(listener);
206206
skipListeners.add((SkipListener<I, O>) factory.getObject());
207207
}
208+
else if (!listenerErrors.isEmpty()) {
209+
listenerErrors.add(new IllegalArgumentException(
210+
"Missing @OnSkipInRead, @OnSkipInProcess or @OnSkipInWrite annotations on Listener."));
211+
}
208212

209213
return this;
210214
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FlowStepBuilder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ public Step build() {
6060
step.setName(getName());
6161
step.setFlow(flow);
6262
super.enhance(step);
63+
if (!listenerErrors.isEmpty()) {
64+
throw new StepBuilderException(
65+
new IllegalArgumentException("Errors occurred while registering listeners" + listenerErrors));
66+
}
6367
try {
6468
step.afterPropertiesSet();
6569
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/JobStepBuilder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ public Step build() {
8686
JobStep step = new JobStep();
8787
step.setName(getName());
8888
super.enhance(step);
89+
if (!listenerErrors.isEmpty()) {
90+
throw new StepBuilderException(
91+
new IllegalArgumentException("Errors occurred while registering listeners" + listenerErrors));
92+
}
8993
if (job != null) {
9094
step.setJob(job);
9195
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/PartitionStepBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ public Step build() {
163163
step.setName(getName());
164164
super.enhance(step);
165165

166+
if (!listenerErrors.isEmpty()) {
167+
throw new StepBuilderException(
168+
new IllegalArgumentException("Errors occurred while registering listeners" + listenerErrors));
169+
}
170+
166171
if (partitionHandler != null) {
167172
step.setPartitionHandler(partitionHandler);
168173
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,15 @@ public SimpleStepBuilder<I, O> listener(Object listener) {
270270
itemListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), OnWriteError.class));
271271

272272
if (!itemListenerMethods.isEmpty()) {
273+
listenerErrors.clear();
273274
StepListenerFactoryBean factory = new StepListenerFactoryBean();
274275
factory.setDelegate(listener);
275276
itemListeners.add((StepListener) factory.getObject());
276277
}
278+
else if (!listenerErrors.isEmpty()) {
279+
listenerErrors.add(new IllegalArgumentException(
280+
"Missing @BeforeRead, @AfterRead, @BeforeProcess, @AfterProcess, @BeforeWrite, @AfterWrite, @OnReadError, @OnProcessError or @OnWriteError annotations on Listener."));
281+
}
277282

278283
return this;
279284
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public abstract class StepBuilderHelper<B extends StepBuilderHelper<B>> {
5353

5454
protected final CommonStepProperties properties;
5555

56+
protected List<Throwable> listenerErrors = new ArrayList<>();
57+
5658
/**
5759
* Create a new {@link StepBuilderHelper} with the given job repository.
5860
* @param jobRepository the job repository
@@ -82,6 +84,7 @@ public StepBuilderHelper(String name, JobRepository jobRepository) {
8284
*/
8385
protected StepBuilderHelper(StepBuilderHelper<?> parent) {
8486
this.properties = new CommonStepProperties(parent.properties);
87+
this.listenerErrors = parent.listenerErrors;
8588
}
8689

8790
/**
@@ -126,7 +129,8 @@ public B listener(Object listener) {
126129
properties.addStepExecutionListener((StepExecutionListener) factory.getObject());
127130
}
128131
else {
129-
throw new IllegalArgumentException("Missing @BeforeStep or @AfterStep annotations on Listener.");
132+
listenerErrors
133+
.add(new IllegalArgumentException("Missing @BeforeStep or @AfterStep annotations on Listener."));
130134
}
131135

132136
return self();

0 commit comments

Comments
 (0)