Skip to content

Commit b28238e

Browse files
dimitrislifmbenhassine
authored andcommitted
Explicitly considering Start Time not being null for running Job Executions
This is to exclude from capturing erroneous Job Executions. An example is whenever a TaskRejectedException is thrown after submitting to the taskExecutor in SimpleJobLauncher#run(), the JobExecution is left without a Start or End Time. Also related tests are fixed. Resolves BATCH-2675
1 parent 2876930 commit b28238e

File tree

10 files changed

+70
-20
lines changed

10 files changed

+70
-20
lines changed

spring-batch-core-tests/src/test/java/org/springframework/batch/core/test/repository/JdbcJobRepositoryTests.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2013 the original author or authors.
2+
* Copyright 2006-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
2323
import java.io.Serializable;
2424
import java.sql.Timestamp;
2525
import java.util.ArrayList;
26+
import java.util.Date;
2627
import java.util.HashSet;
2728
import java.util.List;
2829
import java.util.Set;
@@ -202,6 +203,11 @@ public void run() {
202203

203204
try {
204205
JobExecution execution = repository.createJobExecution(job.getName(), new JobParameters());
206+
207+
//simulate running execution
208+
execution.setStartTime(new Date());
209+
repository.update(execution);
210+
205211
cacheJobIds(execution);
206212
list.add(execution);
207213
Thread.sleep(1000);

spring-batch-core/src/main/java/org/springframework/batch/core/JobExecution.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2013 the original author or authors.
2+
* Copyright 2006-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@
3535
*
3636
* @author Lucas Ward
3737
* @author Michael Minella
38+
* @author Dimitrios Liapis
3839
*
3940
*/
4041
@SuppressWarnings("serial")
@@ -224,10 +225,10 @@ public StepExecution createStepExecution(String stepName) {
224225
* Test if this {@link JobExecution} indicates that it is running. It should
225226
* be noted that this does not necessarily mean that it has been persisted
226227
* as such yet.
227-
* @return true if the end time is null
228+
* @return true if the end time is null and the start time is not null
228229
*/
229230
public boolean isRunning() {
230-
return endTime == null;
231+
return startTime != null && endTime == null;
231232
}
232233

233234
/**

spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2013 the original author or authors.
2+
* Copyright 2006-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -58,6 +58,7 @@
5858
* @author Dave Syer
5959
* @author Robert Kasanicky
6060
* @author Michael Minella
61+
* @author Dimitrios Liapis
6162
*/
6263
public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements JobExecutionDao, InitializingBean {
6364

@@ -83,7 +84,7 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements
8384
+ " from %PREFIX%JOB_EXECUTION where JOB_EXECUTION_ID = ?";
8485

8586
private static final String GET_RUNNING_EXECUTIONS = "SELECT E.JOB_EXECUTION_ID, E.START_TIME, E.END_TIME, E.STATUS, E.EXIT_CODE, E.EXIT_MESSAGE, E.CREATE_TIME, E.LAST_UPDATED, E.VERSION, "
86-
+ "E.JOB_INSTANCE_ID, E.JOB_CONFIGURATION_LOCATION from %PREFIX%JOB_EXECUTION E, %PREFIX%JOB_INSTANCE I where E.JOB_INSTANCE_ID=I.JOB_INSTANCE_ID and I.JOB_NAME=? and E.END_TIME is NULL order by E.JOB_EXECUTION_ID desc";
87+
+ "E.JOB_INSTANCE_ID, E.JOB_CONFIGURATION_LOCATION from %PREFIX%JOB_EXECUTION E, %PREFIX%JOB_INSTANCE I where E.JOB_INSTANCE_ID=I.JOB_INSTANCE_ID and I.JOB_NAME=? and E.START_TIME is not NULL and E.END_TIME is NULL order by E.JOB_EXECUTION_ID desc";
8788

8889
private static final String CURRENT_VERSION_JOB_EXECUTION = "SELECT VERSION FROM %PREFIX%JOB_EXECUTION WHERE JOB_EXECUTION_ID=?";
8990

spring-batch-core/src/test/java/org/springframework/batch/core/JobExecutionTests.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2014 the original author or authors.
2+
* Copyright 2006-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
3030

3131
/**
3232
* @author Dave Syer
33+
* @author Dimitrios Liapis
3334
*
3435
*/
3536
public class JobExecutionTests {
@@ -65,6 +66,7 @@ public void testGetJobConfigurationName() {
6566
*/
6667
@Test
6768
public void testIsRunning() {
69+
execution.setStartTime(new Date());
6870
assertTrue(execution.isRunning());
6971
execution.setEndTime(new Date(100L));
7072
assertFalse(execution.isRunning());
@@ -76,6 +78,7 @@ public void testIsRunning() {
7678
*/
7779
@Test
7880
public void testIsRunningWithStoppedExecution() {
81+
execution.setStartTime(new Date());
7982
assertTrue(execution.isRunning());
8083
execution.stop();
8184
assertTrue(execution.isRunning());

spring-batch-core/src/test/java/org/springframework/batch/core/explore/support/MapJobExplorerFactoryBeanTests.java

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2014 the original author or authors.
2+
* Copyright 2010-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,11 +18,14 @@
1818
import static org.junit.Assert.assertEquals;
1919

2020
import org.junit.Test;
21+
import org.springframework.batch.core.JobExecution;
2122
import org.springframework.batch.core.JobParameters;
2223
import org.springframework.batch.core.explore.JobExplorer;
23-
import org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean;
24+
import org.springframework.batch.core.repository.JobRepository;
2425
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
2526

27+
import java.util.Date;
28+
2629
/**
2730
* Tests for {@link MapJobExplorerFactoryBean}.
2831
*/
@@ -36,8 +39,13 @@ public class MapJobExplorerFactoryBeanTests {
3639
public void testCreateExplorer() throws Exception {
3740

3841
MapJobRepositoryFactoryBean repositoryFactory = new MapJobRepositoryFactoryBean();
39-
repositoryFactory.getObject().createJobExecution("foo", new JobParameters());
40-
42+
JobRepository jobRepository = repositoryFactory.getObject();
43+
JobExecution jobExecution = jobRepository.createJobExecution("foo", new JobParameters());
44+
45+
//simulating a running job execution
46+
jobExecution.setStartTime(new Date());
47+
jobRepository.update(jobExecution);
48+
4149
MapJobExplorerFactoryBean tested = new MapJobExplorerFactoryBean(repositoryFactory);
4250
tested.afterPropertiesSet();
4351

spring-batch-core/src/test/java/org/springframework/batch/core/jsr/launch/JsrJobOperatorTests.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013 the original author or authors.
2+
* Copyright 2013-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -79,6 +79,9 @@
7979
import org.springframework.test.util.ReflectionTestUtils;
8080
import org.springframework.transaction.PlatformTransactionManager;
8181

82+
/**
83+
* Tests for {@link JsrJobOperator}.
84+
*/
8285
public class JsrJobOperatorTests extends AbstractJsrTestCase {
8386

8487
private JobOperator jsrJobOperator;
@@ -225,6 +228,8 @@ public void testAbandonNoSuchJob() throws Exception {
225228
@Test(expected=JobExecutionIsRunningException.class)
226229
public void testAbandonJobRunning() throws Exception {
227230
JobExecution jobExecution = new JobExecution(5L);
231+
jobExecution.setStartTime(new Date(1L));
232+
228233
when(jobExplorer.getJobExecution(5L)).thenReturn(jobExecution);
229234

230235
jsrJobOperator.abandon(5L);

spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractJobExecutionDaoTests.java

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2008-2014 the original author or authors.
2+
* Copyright 2008-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,6 +38,9 @@
3838
import org.springframework.transaction.annotation.Transactional;
3939
import org.springframework.util.Assert;
4040

41+
/**
42+
* Parent Test Class for {@link JdbcJobExecutionDao} and {@link MapJobExecutionDao}.
43+
*/
4144
public abstract class AbstractJobExecutionDaoTests {
4245

4346
protected JobExecutionDao dao;
@@ -193,14 +196,24 @@ public void testGetMissingLastExecution() {
193196
@Transactional
194197
@Test
195198
public void testFindRunningExecutions() {
196-
199+
//Normally completed JobExecution as EndTime is populated
197200
JobExecution exec = new JobExecution(jobInstance, jobParameters);
198201
exec.setCreateTime(new Date(0));
199-
exec.setEndTime(new Date(1L));
202+
exec.setStartTime(new Date(1L));
203+
exec.setEndTime(new Date(2L));
204+
exec.setLastUpdated(new Date(5L));
205+
dao.saveJobExecution(exec);
206+
207+
//BATCH-2675
208+
//Abnormal JobExecution as both StartTime and EndTime are null
209+
//This can occur when SimpleJobLauncher#run() submission to taskExecutor throws a TaskRejectedException
210+
exec = new JobExecution(jobInstance, jobParameters);
200211
exec.setLastUpdated(new Date(5L));
201212
dao.saveJobExecution(exec);
202213

214+
//Running JobExecution as StartTime is populated but EndTime is null
203215
exec = new JobExecution(jobInstance, jobParameters);
216+
exec.setStartTime(new Date(2L));
204217
exec.setLastUpdated(new Date(5L));
205218
exec.createStepExecution("step");
206219
dao.saveJobExecution(exec);

spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/OptimisticLockingFailureTests.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014 the original author or authors.
2+
* Copyright 2014-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -72,6 +72,8 @@ public void testAsyncStopOfStartingJob() throws Exception {
7272
.addLong("test", 1L)
7373
.toJobParameters());
7474

75+
Thread.sleep(1000);
76+
7577
while(restartJobExecution.isRunning()) {
7678
// wait for async launched job to complete execution
7779
}

spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/MapJobRepositoryFactoryBeanTests.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2008-2014 the original author or authors.
2+
* Copyright 2008-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,11 +17,14 @@
1717

1818
import org.junit.Test;
1919
import org.springframework.batch.core.Job;
20+
import org.springframework.batch.core.JobExecution;
2021
import org.springframework.batch.core.JobParameters;
2122
import org.springframework.batch.core.job.JobSupport;
2223
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
2324
import org.springframework.batch.core.repository.JobRepository;
2425

26+
import java.util.Date;
27+
2528
import static org.junit.Assert.fail;
2629

2730
/**
@@ -42,7 +45,11 @@ public void testCreateRepository() throws Exception {
4245
Job job = new JobSupport("jobName");
4346
JobParameters jobParameters = new JobParameters();
4447

45-
repository.createJobExecution(job.getName(), jobParameters);
48+
JobExecution jobExecution = repository.createJobExecution(job.getName(), jobParameters);
49+
50+
// simulate a running execution
51+
jobExecution.setStartTime(new Date());
52+
repository.update(jobExecution);
4653

4754
try {
4855
repository.createJobExecution(job.getName(), jobParameters);

spring-batch-core/src/test/java/org/springframework/batch/core/repository/support/SimpleJobRepositoryIntegrationTests.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2008-2014 the original author or authors.
2+
* Copyright 2008-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@
4343
* Repository tests using JDBC DAOs (rather than mocks).
4444
*
4545
* @author Robert Kasanicky
46+
* @author Dimitrios Liapis
4647
*/
4748
@RunWith(SpringJUnit4ClassRunner.class)
4849
@ContextConfiguration(locations = "/org/springframework/batch/core/repository/dao/sql-dao-test.xml")
@@ -180,8 +181,11 @@ public void testSaveExecutionContext() throws Exception {
180181
@Test
181182
public void testOnlyOneJobExecutionAllowedRunning() throws Exception {
182183
job.setRestartable(true);
183-
jobRepository.createJobExecution(job.getName(), jobParameters);
184+
JobExecution jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
184185

186+
//simulating a running job execution
187+
jobExecution.setStartTime(new Date());
188+
jobRepository.update(jobExecution);
185189
try {
186190
jobRepository.createJobExecution(job.getName(), jobParameters);
187191
fail();

0 commit comments

Comments
 (0)