Skip to content

Commit 8dde852

Browse files
committed
Make JobOperator use domain types in method signatures
Resolves #4845
1 parent f7fcfaa commit 8dde852

File tree

2 files changed

+158
-6
lines changed

2 files changed

+158
-6
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/launch/JobOperator.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.batch.core.JobParametersInvalidException;
2929
import org.springframework.batch.core.StepExecution;
3030
import org.springframework.batch.core.UnexpectedJobExecutionException;
31+
import org.springframework.batch.core.configuration.JobRegistry;
3132
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
3233
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
3334
import org.springframework.batch.core.repository.JobRestartException;
@@ -46,7 +47,10 @@ public interface JobOperator extends JobLauncher {
4647
* List the available job names that can be launched with
4748
* {@link #start(String, Properties)}.
4849
* @return a set of job names
50+
* @deprecated since 6.0 in favor of {@link JobRegistry#getJobNames()}. Scheduled for
51+
* removal in 6.2 or later.
4952
*/
53+
@Deprecated(since = "6.0", forRemoval = true)
5054
Set<String> getJobNames();
5155

5256
/**
@@ -104,10 +108,32 @@ default JobExecution start(Job job, JobParameters jobParameters)
104108
* @throws JobRestartException if there is a non-specific error with the restart (e.g.
105109
* corrupt or inconsistent restart data)
106110
* @throws JobParametersInvalidException if the parameters are not valid for this job
111+
* @deprecated since 6.0 in favor of {@link #restart(JobExecution)}. Scheduled for
112+
* removal in 6.2 or later.
107113
*/
114+
@Deprecated(since = "6.0", forRemoval = true)
108115
Long restart(long executionId) throws JobInstanceAlreadyCompleteException, NoSuchJobExecutionException,
109116
NoSuchJobException, JobRestartException, JobParametersInvalidException;
110117

118+
/**
119+
* Restart a failed or stopped {@link JobExecution}. Fails with an exception if the
120+
* execution provided does not exist or corresponds to a {@link JobInstance} that in
121+
* normal circumstances already completed successfully.
122+
* @param jobExecution the failed or stopped {@link JobExecution} to restart
123+
* @return the {@link JobExecution} that was started
124+
* @throws JobInstanceAlreadyCompleteException if the job was already successfully
125+
* completed
126+
* @throws NoSuchJobExecutionException if the id was not associated with any
127+
* {@link JobExecution}
128+
* @throws NoSuchJobException if the {@link JobExecution} was found, but its
129+
* corresponding {@link Job} is no longer available for launching
130+
* @throws JobRestartException if there is a non-specific error with the restart (e.g.
131+
* corrupt or inconsistent restart data)
132+
* @throws JobParametersInvalidException if the parameters are not valid for this job
133+
*/
134+
JobExecution restart(JobExecution jobExecution) throws JobInstanceAlreadyCompleteException,
135+
NoSuchJobExecutionException, NoSuchJobException, JobRestartException, JobParametersInvalidException;
136+
111137
/**
112138
* Launch the next in a sequence of {@link JobInstance} determined by the
113139
* {@link JobParametersIncrementer} attached to the specified job. If the previous
@@ -132,11 +158,42 @@ Long restart(long executionId) throws JobInstanceAlreadyCompleteException, NoSuc
132158
* that is already executing.
133159
* @throws JobInstanceAlreadyCompleteException thrown if attempting to restart a
134160
* completed job.
161+
* @deprecated since 6.0 in favor of {@link #startNextInstance(Job)}. Scheduled for
162+
* removal in 6.2 or later.
135163
*/
164+
@Deprecated(since = "6.0", forRemoval = true)
136165
Long startNextInstance(String jobName) throws NoSuchJobException, JobParametersNotFoundException,
137166
JobRestartException, JobExecutionAlreadyRunningException, JobInstanceAlreadyCompleteException,
138167
UnexpectedJobExecutionException, JobParametersInvalidException;
139168

169+
/**
170+
* Launch the next in a sequence of {@link JobInstance} determined by the
171+
* {@link JobParametersIncrementer} attached to the specified job. If the previous
172+
* instance is still in a failed state, this method should still create a new instance
173+
* and run it with different parameters (as long as the
174+
* {@link JobParametersIncrementer} is working).<br>
175+
* <br>
176+
*
177+
* The last three exception described below should be extremely unlikely, but cannot
178+
* be ruled out entirely. It points to some other thread or process trying to use this
179+
* method (or a similar one) at the same time.
180+
* @param job the job to launch
181+
* @return the {@link JobExecution} created when the job is launched
182+
* @throws NoSuchJobException if there is no such job definition available
183+
* @throws JobParametersNotFoundException if the parameters cannot be found
184+
* @throws JobParametersInvalidException thrown if some of the job parameters are
185+
* invalid.
186+
* @throws UnexpectedJobExecutionException if an unexpected condition arises
187+
* @throws JobRestartException thrown if a job is restarted illegally.
188+
* @throws JobExecutionAlreadyRunningException thrown if attempting to restart a job
189+
* that is already executing.
190+
* @throws JobInstanceAlreadyCompleteException thrown if attempting to restart a
191+
* completed job.
192+
*/
193+
JobExecution startNextInstance(Job job) throws NoSuchJobException, JobParametersNotFoundException,
194+
JobRestartException, JobExecutionAlreadyRunningException, JobInstanceAlreadyCompleteException,
195+
UnexpectedJobExecutionException, JobParametersInvalidException;
196+
140197
/**
141198
* Send a stop signal to the {@link JobExecution} with the supplied id. The signal is
142199
* successfully sent if this method returns true, but that doesn't mean that the job
@@ -148,9 +205,24 @@ Long startNextInstance(String jobName) throws NoSuchJobException, JobParametersN
148205
* supplied
149206
* @throws JobExecutionNotRunningException if the {@link JobExecution} is not running
150207
* (so cannot be stopped)
208+
* @deprecated since 6.0 in favor of {@link #stop(JobExecution)}. Scheduled for
209+
* removal in 6.2 or later.
151210
*/
211+
@Deprecated(since = "6.0", forRemoval = true)
152212
boolean stop(long executionId) throws NoSuchJobExecutionException, JobExecutionNotRunningException;
153213

214+
/**
215+
* Send a stop signal to the supplied {@link JobExecution}. The signal is successfully
216+
* sent if this method returns true, but that doesn't mean that the job has stopped.
217+
* The only way to be sure of that is to poll the job execution status.
218+
* @param jobExecution the running {@link JobExecution}
219+
* @return true if the message was successfully sent (does not guarantee that the job
220+
* has stopped)
221+
* @throws JobExecutionNotRunningException if the supplied {@link JobExecution} is not
222+
* running (so cannot be stopped)
223+
*/
224+
boolean stop(JobExecution jobExecution) throws JobExecutionNotRunningException;
225+
154226
/**
155227
* Mark the {@link JobExecution} as ABANDONED. If a stop signal is ignored because the
156228
* process died this is the best way to mark a job as finished with (as opposed to
@@ -161,9 +233,23 @@ Long startNextInstance(String jobName) throws NoSuchJobException, JobParametersN
161233
* jobExecutionId.
162234
* @throws JobExecutionAlreadyRunningException if the job is running (it should be
163235
* stopped first)
236+
* @deprecated since 6.0 in favor of {@link #abandon(JobExecution)}. Scheduled for
237+
* removal in 6.2 or later.
164238
*/
239+
@Deprecated(since = "6.0", forRemoval = true)
165240
JobExecution abandon(long jobExecutionId) throws NoSuchJobExecutionException, JobExecutionAlreadyRunningException;
166241

242+
/**
243+
* Mark the {@link JobExecution} as ABANDONED. If a stop signal is ignored because the
244+
* process died this is the best way to mark a job as finished with (as opposed to
245+
* STOPPED). An abandoned job execution cannot be restarted by the framework.
246+
* @param jobExecution the job execution to abort
247+
* @return the {@link JobExecution} that was aborted
248+
* @throws JobExecutionAlreadyRunningException if the job execution is running (it
249+
* should be stopped first)
250+
*/
251+
JobExecution abandon(JobExecution jobExecution) throws JobExecutionAlreadyRunningException;
252+
167253
/**
168254
* List the {@link JobExecution JobExecutions} associated with a particular
169255
* {@link JobInstance}, in reverse order of creation (and therefore usually of

spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/SimpleJobOperator.java

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,7 @@ public void setJobRegistry(ListableJobLocator jobRegistry) {
125125
}
126126

127127
@Override
128-
public Set<String> getJobNames() {
129-
return new TreeSet<>(jobRegistry.getJobNames());
130-
}
131-
132-
@Override
128+
@Deprecated(since = "6.0", forRemoval = true)
133129
public Long start(String jobName, Properties parameters)
134130
throws NoSuchJobException, JobInstanceAlreadyExistsException, JobParametersInvalidException {
135131
if (logger.isInfoEnabled()) {
@@ -168,6 +164,7 @@ public Long start(String jobName, Properties parameters)
168164
}
169165

170166
@Override
167+
@Deprecated(since = "6.0", forRemoval = true)
171168
public Long restart(long executionId) throws JobInstanceAlreadyCompleteException, NoSuchJobExecutionException,
172169
NoSuchJobException, JobRestartException, JobParametersInvalidException {
173170

@@ -194,6 +191,28 @@ public Long restart(long executionId) throws JobInstanceAlreadyCompleteException
194191
}
195192

196193
@Override
194+
public JobExecution restart(JobExecution jobExecution) throws JobInstanceAlreadyCompleteException,
195+
NoSuchJobExecutionException, NoSuchJobException, JobRestartException, JobParametersInvalidException {
196+
197+
String jobName = jobExecution.getJobInstance().getJobName();
198+
Job job = jobRegistry.getJob(jobName);
199+
JobParameters parameters = jobExecution.getJobParameters();
200+
201+
if (logger.isInfoEnabled()) {
202+
logger.info(String.format("Attempting to resume job with name=%s and parameters=%s", jobName, parameters));
203+
}
204+
try {
205+
return run(job, parameters);
206+
}
207+
catch (JobExecutionAlreadyRunningException e) {
208+
throw new UnexpectedJobExecutionException(
209+
String.format(ILLEGAL_STATE_MSG, "job execution already running", jobName, parameters), e);
210+
}
211+
212+
}
213+
214+
@Override
215+
@Deprecated(since = "6.0", forRemoval = true)
197216
public Long startNextInstance(String jobName)
198217
throws NoSuchJobException, UnexpectedJobExecutionException, JobParametersInvalidException {
199218
if (logger.isInfoEnabled()) {
@@ -224,9 +243,43 @@ public Long startNextInstance(String jobName)
224243
}
225244

226245
@Override
246+
public JobExecution startNextInstance(Job job)
247+
throws NoSuchJobException, UnexpectedJobExecutionException, JobParametersInvalidException {
248+
249+
JobParameters parameters = new JobParametersBuilder(jobRepository).getNextJobParameters(job).toJobParameters();
250+
if (logger.isInfoEnabled()) {
251+
logger.info(String.format("Attempting to launch job with name=%s and parameters=%s", job.getName(),
252+
parameters));
253+
}
254+
try {
255+
return run(job, parameters);
256+
}
257+
catch (JobExecutionAlreadyRunningException e) {
258+
throw new UnexpectedJobExecutionException(
259+
String.format(ILLEGAL_STATE_MSG, "job already running", job.getName(), parameters), e);
260+
}
261+
catch (JobRestartException e) {
262+
throw new UnexpectedJobExecutionException(
263+
String.format(ILLEGAL_STATE_MSG, "job not restartable", job.getName(), parameters), e);
264+
}
265+
catch (JobInstanceAlreadyCompleteException e) {
266+
throw new UnexpectedJobExecutionException(
267+
String.format(ILLEGAL_STATE_MSG, "job instance already complete", job.getName(), parameters), e);
268+
}
269+
270+
}
271+
272+
@Override
273+
@Deprecated(since = "6.0", forRemoval = true)
227274
public boolean stop(long executionId) throws NoSuchJobExecutionException, JobExecutionNotRunningException {
228275

229276
JobExecution jobExecution = findExecutionById(executionId);
277+
return stop(jobExecution);
278+
}
279+
280+
@Override
281+
public boolean stop(JobExecution jobExecution) throws JobExecutionNotRunningException {
282+
230283
// Indicate the execution should be stopped by setting it's status to
231284
// 'STOPPING'. It is assumed that
232285
// the step implementation will check this status at chunk boundaries.
@@ -241,7 +294,7 @@ public boolean stop(long executionId) throws NoSuchJobExecutionException, JobExe
241294
try {
242295
Job job = jobRegistry.getJob(jobExecution.getJobInstance().getJobName());
243296
if (job instanceof StepLocator) {// can only process as StepLocator is the
244-
// only way to get the step object
297+
// only way to get the step object
245298
// get the current stepExecution
246299
for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
247300
if (stepExecution.getStatus().isRunning()) {
@@ -272,10 +325,17 @@ public boolean stop(long executionId) throws NoSuchJobExecutionException, JobExe
272325
}
273326

274327
@Override
328+
@Deprecated(since = "6.0", forRemoval = true)
275329
public JobExecution abandon(long jobExecutionId)
276330
throws NoSuchJobExecutionException, JobExecutionAlreadyRunningException {
277331
JobExecution jobExecution = findExecutionById(jobExecutionId);
278332

333+
return abandon(jobExecution);
334+
}
335+
336+
@Override
337+
public JobExecution abandon(JobExecution jobExecution) throws JobExecutionAlreadyRunningException {
338+
279339
if (jobExecution.getStatus().isLessThan(BatchStatus.STOPPING)) {
280340
throw new JobExecutionAlreadyRunningException(
281341
"JobExecution is running or complete and therefore cannot be aborted");
@@ -290,6 +350,12 @@ public JobExecution abandon(long jobExecutionId)
290350
return jobExecution;
291351
}
292352

353+
@Override
354+
@Deprecated(since = "6.0", forRemoval = true)
355+
public Set<String> getJobNames() {
356+
return new TreeSet<>(jobRegistry.getJobNames());
357+
}
358+
293359
@Override
294360
@Deprecated(since = "6.0", forRemoval = true)
295361
public List<Long> getExecutions(long instanceId) throws NoSuchJobInstanceException {

0 commit comments

Comments
 (0)