Refactored launching to allow exit codes to be returned to the launcher.
This commit is contained in:
@@ -35,7 +35,7 @@ public class JobExecution extends Entity {
|
||||
|
||||
private Long jobId;
|
||||
|
||||
private int exitCode;
|
||||
private String exitCode = "";
|
||||
|
||||
// Package private constructor for Hibernate
|
||||
JobExecution() {}
|
||||
@@ -85,14 +85,14 @@ public class JobExecution extends Entity {
|
||||
/**
|
||||
* @param exitCode
|
||||
*/
|
||||
public void setExitCode(int exitCode) {
|
||||
public void setExitCode(String exitCode) {
|
||||
this.exitCode = exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the exitCode
|
||||
*/
|
||||
public int getExitCode() {
|
||||
public String getExitCode() {
|
||||
return exitCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,11 @@ public class StepExecution extends Entity {
|
||||
|
||||
private Long jobExecutionId;
|
||||
|
||||
private int exitCode;
|
||||
private String exitCode = "";
|
||||
|
||||
private String exitDescription = "";
|
||||
|
||||
private Throwable exception;
|
||||
|
||||
/**
|
||||
* Package private constructor for Hibernate
|
||||
@@ -176,15 +180,30 @@ public class StepExecution extends Entity {
|
||||
/**
|
||||
* @param exitCode
|
||||
*/
|
||||
public void setExitCode(int exitCode) {
|
||||
public void setExitCode(String exitCode) {
|
||||
this.exitCode = exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the exitCode
|
||||
*/
|
||||
public int getExitCode() {
|
||||
public String getExitCode() {
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
public void setException(Throwable exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
public Throwable getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
public void setExitDescription(String exitDescription) {
|
||||
this.exitDescription = exitDescription;
|
||||
}
|
||||
|
||||
public String getExitDescription() {
|
||||
return exitDescription;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.batch.core.executor;
|
||||
import org.springframework.batch.core.configuration.JobConfiguration;
|
||||
import org.springframework.batch.core.runtime.JobExecutionContext;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* Interface for running a job from its configuration.
|
||||
@@ -30,6 +31,6 @@ import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
*/
|
||||
public interface JobExecutor {
|
||||
|
||||
public void run(JobConfiguration configuration, JobExecutionContext jobExecutionContext) throws BatchCriticalException;
|
||||
public ExitStatus run(JobConfiguration configuration, JobExecutionContext jobExecutionContext) throws BatchCriticalException;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.batch.core.tasklet;
|
||||
|
||||
import org.springframework.batch.core.configuration.StepConfiguration;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* The primary interface describing the touch-point between the batch developer
|
||||
@@ -46,9 +47,10 @@ public interface Tasklet {
|
||||
* outside of this method will prevent the architecture from gracefully
|
||||
* shutting down and providing such features as transaction rollback.
|
||||
*
|
||||
* @return boolean indicating whether the processing should continue (i.e.
|
||||
* @return ExitStatus indicating whether the processing should continue (i.e.
|
||||
* false when data are exhausted).
|
||||
* @see org.springframework.batch.repeat.ExitStatus
|
||||
*/
|
||||
public boolean execute() throws Exception;
|
||||
public ExitStatus execute() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.batch.core.configuration;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -58,8 +59,8 @@ public class StepConfigurationSupportTests extends TestCase {
|
||||
public void testGetTasklet() {
|
||||
assertEquals(null, configuration.getTasklet());
|
||||
Tasklet tasklet = new Tasklet() {
|
||||
public boolean execute() throws Exception {
|
||||
return false;
|
||||
public ExitStatus execute() throws Exception {
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
};
|
||||
configuration.setTasklet(tasklet);
|
||||
|
||||
@@ -74,9 +74,9 @@ public class JobExecutionTests extends TestCase {
|
||||
* Test method for {@link org.springframework.batch.core.domain.JobExecution#getExitCode()}.
|
||||
*/
|
||||
public void testGetExitCode() {
|
||||
assertEquals(0, execution.getExitCode());
|
||||
execution.setExitCode(23);
|
||||
assertEquals(23, execution.getExitCode());
|
||||
assertEquals("", execution.getExitCode());
|
||||
execution.setExitCode("23");
|
||||
assertEquals("23", execution.getExitCode());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,9 +73,9 @@ public class StepExecutionTests extends TestCase {
|
||||
* Test method for {@link org.springframework.batch.core.domain.JobExecution#getExitCode()}.
|
||||
*/
|
||||
public void testGetExitCode() {
|
||||
assertEquals(0, execution.getExitCode());
|
||||
execution.setExitCode(23);
|
||||
assertEquals(23, execution.getExitCode());
|
||||
assertEquals("", execution.getExitCode());
|
||||
execution.setExitCode("23");
|
||||
assertEquals("23", execution.getExitCode());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,3 +188,4 @@ public class StepExecutionTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.batch.execution;
|
||||
|
||||
import org.springframework.batch.core.configuration.NoSuchJobConfigurationException;
|
||||
import org.springframework.batch.core.runtime.JobIdentifier;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* Interface which defines a facade for running jobs. The interface is
|
||||
@@ -40,7 +41,7 @@ public interface JobExecutorFacade {
|
||||
*
|
||||
* @throws NoSuchJobConfigurationException
|
||||
*/
|
||||
void start(JobIdentifier runtimeInformation) throws NoSuchJobConfigurationException;
|
||||
ExitStatus start(JobIdentifier runtimeInformation) throws NoSuchJobConfigurationException;
|
||||
|
||||
/**
|
||||
* Stop the job execution that was started with this runtime information.
|
||||
|
||||
@@ -35,7 +35,7 @@ public class BatchCommandLineLauncher {
|
||||
|
||||
private ConfigurableApplicationContext parent;
|
||||
|
||||
private JobLauncher launcher;
|
||||
private SynchronousJobLauncher launcher;
|
||||
|
||||
/**
|
||||
* Default constructor for the launcher. Sets up the parent context to use
|
||||
@@ -51,7 +51,7 @@ public class BatchCommandLineLauncher {
|
||||
*
|
||||
* @param launcher the launcher to set
|
||||
*/
|
||||
public void setLauncher(JobLauncher launcher) {
|
||||
public void setLauncher(SynchronousJobLauncher launcher) {
|
||||
this.launcher = launcher;
|
||||
}
|
||||
|
||||
@@ -70,10 +70,10 @@ public class BatchCommandLineLauncher {
|
||||
try {
|
||||
if (!launcher.isRunning()) {
|
||||
if (jobName == null) {
|
||||
launcher.start();
|
||||
launcher.run();
|
||||
}
|
||||
else {
|
||||
launcher.start(jobName);
|
||||
launcher.run(jobName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,17 @@
|
||||
|
||||
package org.springframework.batch.execution.bootstrap;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.core.configuration.JobConfiguration;
|
||||
import org.springframework.batch.core.configuration.NoSuchJobConfigurationException;
|
||||
import org.springframework.batch.core.runtime.JobIdentifier;
|
||||
import org.springframework.batch.core.runtime.JobIdentifierFactory;
|
||||
import org.springframework.batch.execution.JobExecutorFacade;
|
||||
import org.springframework.batch.execution.runtime.ScheduledJobIdentifierFactory;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.context.Lifecycle;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple bootstrapping mechanism for running a single job execution in a
|
||||
@@ -36,11 +43,29 @@ import org.springframework.context.Lifecycle;
|
||||
* @author Dave Syer
|
||||
* @since 2.1
|
||||
*/
|
||||
public class SimpleJobLauncher extends AbstractJobLauncher {
|
||||
public class SimpleJobLauncher implements SynchronousJobLauncher {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SimpleJobLauncher.class);
|
||||
|
||||
private volatile Thread processingThread;
|
||||
|
||||
private volatile boolean running = false;
|
||||
|
||||
private JobExecutorFacade jobExecutorFacade;
|
||||
|
||||
private JobIdentifierFactory jobIdentifierFactory = new ScheduledJobIdentifierFactory();;
|
||||
|
||||
private String jobConfigurationName;
|
||||
|
||||
/**
|
||||
* Check that mandatory properties are set.
|
||||
*
|
||||
* @see #setBatchContainer(JobExecutorFacade)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(jobExecutorFacade);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the container is currently running. This is done by
|
||||
@@ -51,7 +76,7 @@ public class SimpleJobLauncher extends AbstractJobLauncher {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the provided container. The current thread will first be saved.
|
||||
* Start the provided facade. The current thread will first be saved.
|
||||
* This may seem odd at first, however, this simple bootstrap requires that
|
||||
* only one thread can kick off a container, and that the first thread that
|
||||
* calls start is the 'processing thread'. If the container has already been
|
||||
@@ -61,26 +86,64 @@ public class SimpleJobLauncher extends AbstractJobLauncher {
|
||||
*
|
||||
* @throws IllegalStateException if JobConfiguration is null.
|
||||
*/
|
||||
protected void doStart(JobIdentifier jobIdentifier) throws NoSuchJobConfigurationException {
|
||||
public ExitStatus run(JobIdentifier jobIdentifier) throws NoSuchJobConfigurationException {
|
||||
|
||||
Assert.notNull(jobIdentifier, "JobIdentifier must not be null.");
|
||||
Assert.isTrue(!isRunning(), "SynchronousLaunchers can run only one job at at time.");
|
||||
|
||||
/*
|
||||
* There is no reason to kick off a new thread, since only one thread
|
||||
* should be processing at once. However, a handle to the thread should
|
||||
* be maintained to allow for interrupt
|
||||
*/
|
||||
processingThread = Thread.currentThread();
|
||||
// TODO: push this out to a method call in parent inside synchronized
|
||||
// block?
|
||||
|
||||
running = true;
|
||||
try {
|
||||
batchContainer.start(jobIdentifier);
|
||||
return jobExecutorFacade.start(jobIdentifier);
|
||||
}
|
||||
finally {
|
||||
running = false;
|
||||
unregister(jobIdentifier);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a job execution with the given name. If a job is already running
|
||||
* has no effect.
|
||||
*
|
||||
* @param name the name to assign to the job
|
||||
* @throws NoSuchJobConfigurationException
|
||||
*/
|
||||
public ExitStatus run(String name) throws NoSuchJobConfigurationException {
|
||||
JobIdentifier runtimeInformation = jobIdentifierFactory.getJobIdentifier(name);
|
||||
return this.run(runtimeInformation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a job execution with default name and other runtime information
|
||||
* provided by the factory. If a job is already running has no effect. The
|
||||
* default name is taken from the enclosed {@link JobConfiguration}.
|
||||
* @throws NoSuchJobConfigurationException if the job configuration cannot be located
|
||||
*
|
||||
* @see #setJobRuntimeInformationFactory(JobIdentifierFactory)
|
||||
* @see org.springframework.context.Lifecycle#start()
|
||||
*/
|
||||
public ExitStatus run(){
|
||||
if (jobConfigurationName==null) {
|
||||
return new ExitStatus(false, "JOB_CONFIGURATION_NOT_PROVIDED", "No JobConfiguration was " +
|
||||
"provided to the launcher.");
|
||||
}
|
||||
try {
|
||||
return this.run(jobConfigurationName);
|
||||
}
|
||||
catch (NoSuchJobConfigurationException e) {
|
||||
logger.error("JobExecutorFacade failed to find a JobConfiguration" +
|
||||
" for the provided JobIdentifier", e);
|
||||
return new ExitStatus(false, "NO_SUCH_JOB_CONFIGURATION", "JobExecutor Facade failed" +
|
||||
"to find a JobConfiguration for the provided JobIdentifier");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the job if it is running by interrupting its thread. If no job is
|
||||
@@ -89,22 +152,24 @@ public class SimpleJobLauncher extends AbstractJobLauncher {
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.Lifecycle#stop()
|
||||
*/
|
||||
protected void doStop() {
|
||||
public void stop() {
|
||||
|
||||
if (isRunning()) {
|
||||
processingThread.interrupt();
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates to {@link #doStop()}. Since there is only one job running in
|
||||
* this launcher this is OK.
|
||||
*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.Lifecycle#stop()
|
||||
*/
|
||||
protected void doStop(JobIdentifier runtimeInformation) {
|
||||
doStop();
|
||||
|
||||
public void setJobExecutorFacade(JobExecutorFacade jobExecutorFacade) {
|
||||
this.jobExecutorFacade = jobExecutorFacade;
|
||||
}
|
||||
|
||||
public void setJobIdentifierFactory(
|
||||
JobIdentifierFactory jobIdentifierFactory) {
|
||||
this.jobIdentifierFactory = jobIdentifierFactory;
|
||||
}
|
||||
|
||||
public void setJobConfigurationName(String jobConfigurationName) {
|
||||
this.jobConfigurationName = jobConfigurationName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.batch.core.runtime.JobIdentifier;
|
||||
import org.springframework.batch.execution.JobExecutorFacade;
|
||||
import org.springframework.batch.execution.NoSuchJobExecutionException;
|
||||
import org.springframework.batch.execution.job.DefaultJobExecutor;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.statistics.StatisticsProvider;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -113,7 +114,7 @@ public class SimpleJobExecutorFacade implements JobExecutorFacade, StatisticsPro
|
||||
* null
|
||||
*
|
||||
*/
|
||||
public void start(JobIdentifier jobRuntimeInformation) throws NoSuchJobConfigurationException {
|
||||
public ExitStatus start(JobIdentifier jobRuntimeInformation) throws NoSuchJobConfigurationException {
|
||||
|
||||
Assert.notNull(jobRuntimeInformation, "JobRuntimeInformation must not be null.");
|
||||
Assert.notNull(jobRuntimeInformation.getName(), "JobRuntimeInformation name must not be null.");
|
||||
@@ -129,11 +130,13 @@ public class SimpleJobExecutorFacade implements JobExecutorFacade, StatisticsPro
|
||||
|
||||
final JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation);
|
||||
JobExecutionContext jobExecutionContext = jobExecutionRegistry.register(jobRuntimeInformation, job);
|
||||
|
||||
ExitStatus exitStatus = ExitStatus.FAILED;
|
||||
try {
|
||||
synchronized (mutex) {
|
||||
running++;
|
||||
}
|
||||
jobExecutor.run(jobConfiguration, jobExecutionContext);
|
||||
exitStatus = jobExecutor.run(jobConfiguration, jobExecutionContext);
|
||||
}
|
||||
finally {
|
||||
synchronized (mutex) {
|
||||
@@ -144,6 +147,7 @@ public class SimpleJobExecutorFacade implements JobExecutorFacade, StatisticsPro
|
||||
jobExecutionRegistry.unregister(jobRuntimeInformation);
|
||||
}
|
||||
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -51,7 +51,7 @@ public class DefaultJobExecutor implements JobExecutor {
|
||||
|
||||
private StepExecutorFactory stepExecutorResolver = new DefaultStepExecutorFactory();
|
||||
|
||||
public void run(JobConfiguration configuration, JobExecutionContext jobExecutionContext)
|
||||
public ExitStatus run(JobConfiguration configuration, JobExecutionContext jobExecutionContext)
|
||||
throws BatchCriticalException {
|
||||
|
||||
JobInstance job = jobExecutionContext.getJob();
|
||||
@@ -90,6 +90,8 @@ public class DefaultJobExecutor implements JobExecutor {
|
||||
jobExecution.setExitCode(status.getExitCode());
|
||||
jobRepository.saveOrUpdate(jobExecution);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
private void updateStatus(JobExecutionContext jobExecutionContext, BatchStatus status) {
|
||||
|
||||
@@ -227,7 +227,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
|
||||
Object[] parameters = new Object[] { stepExecution.getId(), new Long(0), stepExecution.getStepId(), stepExecution.getJobExecutionId(),
|
||||
stepExecution.getStartTime(), stepExecution.getEndTime(), stepExecution.getStatus().toString(),
|
||||
stepExecution.getCommitCount(), stepExecution.getTaskCount(),
|
||||
PropertiesConverter.propertiesToString(stepExecution.getStatistics()), new Integer(stepExecution.getExitCode()) };
|
||||
PropertiesConverter.propertiesToString(stepExecution.getStatistics()), stepExecution.getExitCode() };
|
||||
jdbcTemplate.update(SAVE_STEP_EXECUTION, parameters);
|
||||
|
||||
}
|
||||
@@ -252,7 +252,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
|
||||
Object[] parameters = new Object[] { stepExecution.getStartTime(), stepExecution.getEndTime(),
|
||||
stepExecution.getStatus().toString(), stepExecution.getCommitCount(),
|
||||
stepExecution.getTaskCount(), PropertiesConverter.propertiesToString(stepExecution.getStatistics()),
|
||||
new Integer(stepExecution.getExitCode()),
|
||||
stepExecution.getExitCode(),
|
||||
stepExecution.getId() };
|
||||
jdbcTemplate.update(UPDATE_STEP_EXECUTION, parameters);
|
||||
|
||||
@@ -292,7 +292,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
|
||||
stepExecution.setCommitCount(rs.getInt(6));
|
||||
stepExecution.setTaskCount(rs.getInt(7));
|
||||
stepExecution.setStatistics(PropertiesConverter.stringToProperties(rs.getString(8)));
|
||||
stepExecution.setExitCode(rs.getInt(9));
|
||||
stepExecution.setExitCode(rs.getString(9));
|
||||
return stepExecution;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.springframework.batch.core.domain.StepInstance;
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.core.tasklet.Recoverable;
|
||||
import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
@@ -50,13 +51,13 @@ public class DefaultStepExecutor extends SimpleStepExecutor {
|
||||
* @see org.springframework.batch.execution.step.simple.SimpleStepExecutor#doTaskletProcessing(org.springframework.batch.core.tasklet.Tasklet,
|
||||
* org.springframework.batch.core.domain.StepInstance)
|
||||
*/
|
||||
protected boolean doTaskletProcessing(Tasklet module, final StepInstance step) throws Exception {
|
||||
protected ExitStatus doTaskletProcessing(Tasklet module, final StepInstance step) throws Exception {
|
||||
|
||||
boolean result = true;
|
||||
ExitStatus exitStatus = ExitStatus.CONTINUABLE;
|
||||
|
||||
try {
|
||||
|
||||
result = super.doTaskletProcessing(module, step);
|
||||
exitStatus = super.doTaskletProcessing(module, step);
|
||||
|
||||
}
|
||||
catch (final Exception e) {
|
||||
@@ -80,7 +81,7 @@ public class DefaultStepExecutor extends SimpleStepExecutor {
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -247,10 +247,13 @@ public class SimpleStepExecutor implements StepExecutor {
|
||||
});
|
||||
|
||||
stepExecution.setExitCode(status.getExitCode());
|
||||
stepExecution.setExitDescription(status.getExitDescription());
|
||||
updateStatus(stepExecutionContext, BatchStatus.COMPLETED);
|
||||
return status;
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
|
||||
stepExecution.setException(e);
|
||||
if (e.getCause() instanceof StepInterruptedException) {
|
||||
updateStatus(stepExecutionContext, BatchStatus.STOPPED);
|
||||
throw (StepInterruptedException) e.getCause();
|
||||
@@ -320,11 +323,11 @@ public class SimpleStepExecutor implements StepExecutor {
|
||||
});
|
||||
// check for interruption before each item as well
|
||||
interruptionPolicy.checkInterrupted(context);
|
||||
boolean result = doTaskletProcessing(configuration.getTasklet(), stepExecutionContext.getStep());
|
||||
ExitStatus exitStatus = doTaskletProcessing(configuration.getTasklet(), stepExecutionContext.getStep());
|
||||
stepExecutionContext.getStepExecution().incrementTaskCount();
|
||||
// check for interruption after each item as well
|
||||
interruptionPolicy.checkInterrupted(context);
|
||||
return new ExitStatus(result);
|
||||
return exitStatus;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -338,7 +341,7 @@ public class SimpleStepExecutor implements StepExecutor {
|
||||
* @return boolean if there is more processing to do
|
||||
* @throws Exception if there is an error
|
||||
*/
|
||||
protected boolean doTaskletProcessing(Tasklet tasklet, StepInstance step) throws Exception {
|
||||
protected ExitStatus doTaskletProcessing(Tasklet tasklet, StepInstance step) throws Exception {
|
||||
return tasklet.execute();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.item.ItemProcessor;
|
||||
import org.springframework.batch.item.ItemProvider;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.synch.RepeatSynchronizationManager;
|
||||
import org.springframework.batch.retry.RetryOperations;
|
||||
@@ -132,14 +133,14 @@ public class ItemProviderProcessTasklet implements Tasklet, Recoverable, Skippab
|
||||
*
|
||||
* @see org.springframework.batch.core.tasklet.Tasklet#execute()
|
||||
*/
|
||||
public boolean execute() throws Exception {
|
||||
public ExitStatus execute() throws Exception {
|
||||
if (retryOperations != null) {
|
||||
return retryOperations.execute(new ItemProviderRetryCallback(itemProvider, itemProcessor)) != null;
|
||||
return new ExitStatus(retryOperations.execute(new ItemProviderRetryCallback(itemProvider, itemProcessor)) != null);
|
||||
}
|
||||
else {
|
||||
Object data = itemProvider.next();
|
||||
if (data == null) {
|
||||
return false;
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
RepeatContext context = RepeatSynchronizationManager.getContext();
|
||||
Assert.state(context != null,
|
||||
@@ -149,7 +150,7 @@ public class ItemProviderProcessTasklet implements Tasklet, Recoverable, Skippab
|
||||
// No exception so clear context (we can't recover directly because
|
||||
// the current transaction is going to roll back)
|
||||
context.removeAttribute(ITEM_KEY);
|
||||
return true;
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.batch.execution.tasklet;
|
||||
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* Provides the basic batch module for reading and processing data.
|
||||
@@ -39,12 +40,12 @@ public abstract class ReadProcessTasklet implements Tasklet {
|
||||
* from the abstract read method will be returned to the {@link Tasklet}, to indicate
|
||||
* whether or not processing should continue.
|
||||
*/
|
||||
public final boolean execute() throws Exception {
|
||||
public final ExitStatus execute() throws Exception {
|
||||
if (!read()) {
|
||||
return false;
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
process();
|
||||
return true;
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@ CREATE TABLE BATCH_JOB_EXECUTION (
|
||||
START_TIME TIMESTAMP NOT NULL ,
|
||||
END_TIME TIMESTAMP ,
|
||||
STATUS VARCHAR(10),
|
||||
EXIT_CODE BIGINT);
|
||||
EXIT_CODE VARCHAR(250));
|
||||
|
||||
CREATE TABLE BATCH_STEP (
|
||||
ID BIGINT PRIMARY KEY ,
|
||||
@@ -47,7 +47,7 @@ CREATE TABLE BATCH_STEP_EXECUTION (
|
||||
COMMIT_COUNT BIGINT ,
|
||||
TASK_COUNT BIGINT ,
|
||||
TASK_STATISTICS VARCHAR(250),
|
||||
EXIT_CODE BIGINT,
|
||||
EXIT_CODE VARCHAR(250),
|
||||
EXIT_MESSAGE VARCHAR(250));
|
||||
|
||||
CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
|
||||
|
||||
@@ -26,7 +26,7 @@ CREATE TABLE BATCH_JOB_EXECUTION (
|
||||
START_TIME TIMESTAMP NOT NULL ,
|
||||
END_TIME TIMESTAMP ,
|
||||
STATUS VARCHAR(10),
|
||||
EXIT_CODE BIGINT);
|
||||
EXIT_CODE VARCHAR(250));
|
||||
|
||||
CREATE TABLE BATCH_STEP (
|
||||
ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
|
||||
@@ -47,7 +47,7 @@ CREATE TABLE BATCH_STEP_EXECUTION (
|
||||
COMMIT_COUNT BIGINT ,
|
||||
TASK_COUNT BIGINT ,
|
||||
TASK_STATISTICS VARCHAR(250),
|
||||
EXIT_CODE BIGINT,
|
||||
EXIT_CODE VARCHAR(250),
|
||||
EXIT_MESSAGE VARCHAR(250));
|
||||
|
||||
CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
|
||||
|
||||
@@ -26,7 +26,7 @@ CREATE TABLE BATCH_JOB_EXECUTION (
|
||||
START_TIME TIMESTAMP NOT NULL ,
|
||||
END_TIME TIMESTAMP ,
|
||||
STATUS VARCHAR(10),
|
||||
EXIT_CODE BIGINT);
|
||||
EXIT_CODE VARCHAR(250));
|
||||
|
||||
CREATE TABLE BATCH_STEP (
|
||||
ID BIGINT IDENTITY PRIMARY KEY ,
|
||||
@@ -47,7 +47,7 @@ CREATE TABLE BATCH_STEP_EXECUTION (
|
||||
COMMIT_COUNT BIGINT ,
|
||||
TASK_COUNT BIGINT ,
|
||||
TASK_STATISTICS VARCHAR(250),
|
||||
EXIT_CODE BIGINT,
|
||||
EXIT_CODE VARCHAR(250),
|
||||
EXIT_MESSAGE VARCHAR(250));
|
||||
|
||||
CREATE TABLE BATCH_STEP_EXECUTION_SEQ (
|
||||
|
||||
@@ -26,7 +26,7 @@ CREATE TABLE BATCH_JOB_EXECUTION (
|
||||
START_TIME TIMESTAMP NOT NULL ,
|
||||
END_TIME TIMESTAMP ,
|
||||
STATUS VARCHAR(10),
|
||||
EXIT_CODE INT);
|
||||
EXIT_CODE VARCHAR(250));
|
||||
|
||||
CREATE TABLE BATCH_STEP (
|
||||
ID INT PRIMARY KEY ,
|
||||
@@ -47,7 +47,7 @@ CREATE TABLE BATCH_STEP_EXECUTION (
|
||||
COMMIT_COUNT INT ,
|
||||
TASK_COUNT INT ,
|
||||
TASK_STATISTICS VARCHAR(250),
|
||||
EXIT_CODE INT,
|
||||
EXIT_CODE VARCHAR(250),
|
||||
EXIT_MESSAGE VARCHAR(250));
|
||||
|
||||
CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
|
||||
|
||||
@@ -26,7 +26,7 @@ CREATE TABLE BATCH_JOB_EXECUTION (
|
||||
START_TIME TIMESTAMP NOT NULL ,
|
||||
END_TIME TIMESTAMP ,
|
||||
STATUS VARCHAR(10),
|
||||
EXIT_CODE BIGINT);
|
||||
EXIT_CODE VARCHAR(250));
|
||||
|
||||
CREATE TABLE BATCH_STEP (
|
||||
ID BIGINT PRIMARY KEY ,
|
||||
@@ -47,7 +47,7 @@ CREATE TABLE BATCH_STEP_EXECUTION (
|
||||
COMMIT_COUNT BIGINT ,
|
||||
TASK_COUNT BIGINT ,
|
||||
TASK_STATISTICS VARCHAR(250),
|
||||
EXIT_CODE BIGINT,
|
||||
EXIT_CODE VARCHAR(250),
|
||||
EXIT_MESSAGE VARCHAR(250));
|
||||
|
||||
CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
|
||||
|
||||
@@ -15,7 +15,7 @@ CREATE TABLE BATCH_JOB_EXECUTION (
|
||||
START_TIME TIMESTAMP NOT NULL ,
|
||||
END_TIME TIMESTAMP ,
|
||||
STATUS VARCHAR(10),
|
||||
EXIT_CODE ${BIGINT});
|
||||
EXIT_CODE VARCHAR(250));
|
||||
|
||||
CREATE TABLE BATCH_STEP (
|
||||
ID ${BIGINT} $!{IDENTITY} PRIMARY KEY $!{GENERATED},
|
||||
@@ -36,7 +36,7 @@ CREATE TABLE BATCH_STEP_EXECUTION (
|
||||
COMMIT_COUNT ${BIGINT} ,
|
||||
TASK_COUNT ${BIGINT} ,
|
||||
TASK_STATISTICS VARCHAR(250),
|
||||
EXIT_CODE ${BIGINT},
|
||||
EXIT_CODE VARCHAR(250),
|
||||
EXIT_MESSAGE VARCHAR(250));
|
||||
|
||||
#sequence( "BATCH_STEP_EXECUTION_SEQ" )
|
||||
|
||||
@@ -20,70 +20,24 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.core.configuration.JobConfiguration;
|
||||
import org.springframework.batch.core.configuration.NoSuchJobConfigurationException;
|
||||
import org.springframework.batch.core.runtime.JobIdentifier;
|
||||
import org.springframework.batch.core.runtime.JobIdentifierFactory;
|
||||
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
|
||||
import org.springframework.batch.execution.JobExecutorFacade;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
|
||||
public class SimpleJobLauncherTests extends TestCase {
|
||||
|
||||
public void testAutoStartContainer() throws Exception {
|
||||
|
||||
MockControl containerControl = MockControl.createControl(JobExecutorFacade.class);
|
||||
JobExecutorFacade mockContainer;
|
||||
|
||||
AbstractJobLauncher bootstrap = new SimpleJobLauncher();
|
||||
final SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier("foo");
|
||||
bootstrap.setJobRuntimeInformationFactory(new JobIdentifierFactory() {
|
||||
public JobIdentifier getJobIdentifier(String name) {
|
||||
return runtimeInformation;
|
||||
}
|
||||
});
|
||||
mockContainer = (JobExecutorFacade) containerControl.getMock();
|
||||
bootstrap.setBatchContainer(mockContainer);
|
||||
|
||||
JobConfiguration jobConfiguration = new JobConfiguration("foo");
|
||||
bootstrap.setJobConfigurationName(jobConfiguration.getName());
|
||||
|
||||
mockContainer.start(runtimeInformation);
|
||||
containerControl.replay();
|
||||
|
||||
bootstrap.setAutoStart(true);
|
||||
|
||||
bootstrap.onApplicationEvent(new ContextRefreshedEvent(new GenericApplicationContext()));
|
||||
// It ran and then stopped...
|
||||
assertFalse(bootstrap.isRunning());
|
||||
|
||||
containerControl.verify();
|
||||
}
|
||||
|
||||
public void testApplicationEventNotContextRefresh() throws Exception {
|
||||
|
||||
MockControl containerControl = MockControl.createControl(JobExecutorFacade.class);
|
||||
JobExecutorFacade mockContainer;
|
||||
|
||||
AbstractJobLauncher bootstrap = new SimpleJobLauncher();
|
||||
mockContainer = (JobExecutorFacade) containerControl.getMock();
|
||||
bootstrap.setBatchContainer(mockContainer);
|
||||
|
||||
containerControl.replay();
|
||||
|
||||
bootstrap.setAutoStart(true);
|
||||
|
||||
bootstrap.onApplicationEvent(new ApplicationEvent(new GenericApplicationContext()) {
|
||||
});
|
||||
assertFalse(bootstrap.isRunning());
|
||||
|
||||
containerControl.verify();
|
||||
}
|
||||
|
||||
public void testStartWithNoConfiguration() throws Exception {
|
||||
final AbstractJobLauncher bootstrap = new SimpleJobLauncher();
|
||||
final SimpleJobLauncher launcher = new SimpleJobLauncher();
|
||||
try {
|
||||
bootstrap.afterPropertiesSet();
|
||||
launcher.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
@@ -93,9 +47,9 @@ public class SimpleJobLauncherTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testInitializeWithNoConfiguration() throws Exception {
|
||||
final AbstractJobLauncher bootstrap = new SimpleJobLauncher();
|
||||
final SimpleJobLauncher launcher = new SimpleJobLauncher();
|
||||
try {
|
||||
bootstrap.start();
|
||||
launcher.run();
|
||||
// should do nothing
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -103,83 +57,93 @@ public class SimpleJobLauncherTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testStartTwiceNotFatal() throws Exception {
|
||||
AbstractJobLauncher bootstrap = new SimpleJobLauncher();
|
||||
public void testRunTwiceNotFatal() throws Exception {
|
||||
SimpleJobLauncher launcher = new SimpleJobLauncher();
|
||||
final SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier("foo");
|
||||
bootstrap.setJobRuntimeInformationFactory(new JobIdentifierFactory() {
|
||||
launcher.setJobIdentifierFactory(new JobIdentifierFactory() {
|
||||
public JobIdentifier getJobIdentifier(String name) {
|
||||
return runtimeInformation;
|
||||
}
|
||||
});
|
||||
InterruptibleContainer container = new InterruptibleContainer();
|
||||
bootstrap.setBatchContainer(container);
|
||||
bootstrap.setJobConfigurationName(new JobConfiguration("foo").getName());
|
||||
bootstrap.start();
|
||||
bootstrap.start();
|
||||
InterruptibleFacade jobExecutorFacade = new InterruptibleFacade();
|
||||
launcher.setJobExecutorFacade(jobExecutorFacade);
|
||||
launcher.setJobConfigurationName(new JobConfiguration("foo").getName());
|
||||
launcher.run();
|
||||
launcher.run();
|
||||
// Both jobs finished running because they were not launched in a new
|
||||
// Thread
|
||||
assertFalse(bootstrap.isRunning());
|
||||
assertFalse(launcher.isRunning());
|
||||
}
|
||||
|
||||
public void testInterruptContainer() throws Exception {
|
||||
final AbstractJobLauncher bootstrap = new SimpleJobLauncher();
|
||||
final SimpleJobLauncher launcher = new SimpleJobLauncher();
|
||||
final SimpleJobIdentifier runtimeInformation = new SimpleJobIdentifier("foo");
|
||||
bootstrap.setJobRuntimeInformationFactory(new JobIdentifierFactory() {
|
||||
launcher.setJobIdentifierFactory(new JobIdentifierFactory() {
|
||||
public JobIdentifier getJobIdentifier(String name) {
|
||||
return runtimeInformation;
|
||||
}
|
||||
});
|
||||
|
||||
InterruptibleContainer container = new InterruptibleContainer();
|
||||
bootstrap.setBatchContainer(container);
|
||||
bootstrap.setJobConfigurationName(new JobConfiguration("foo").getName());
|
||||
|
||||
Thread bootstrapThread = new Thread() {
|
||||
InterruptibleFacade jobExecutorFacade = new InterruptibleFacade();
|
||||
launcher.setJobExecutorFacade(jobExecutorFacade);
|
||||
launcher.setJobConfigurationName(new JobConfiguration("foo").getName());
|
||||
|
||||
TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
|
||||
Runnable launcherRunnable = new Runnable() {
|
||||
public void run() {
|
||||
bootstrap.start();
|
||||
System.out.println("run called");
|
||||
launcher.run();
|
||||
System.out.println("run finished.");
|
||||
}
|
||||
};
|
||||
|
||||
bootstrapThread.start();
|
||||
|
||||
taskExecutor.execute(launcherRunnable);
|
||||
|
||||
// give the thread a second to start up
|
||||
System.out.println("first sleep");
|
||||
Thread.sleep(100);
|
||||
assertTrue(bootstrap.isRunning());
|
||||
bootstrap.stop();
|
||||
assertTrue(launcher.isRunning());
|
||||
launcher.stop();
|
||||
Thread.sleep(100);
|
||||
assertFalse(bootstrap.isRunning());
|
||||
assertFalse(launcher.isRunning());
|
||||
}
|
||||
|
||||
public void testStopOnUnstartedContainer() {
|
||||
public void testStopOnUnranLauncher() {
|
||||
|
||||
AbstractJobLauncher bootstrap = new SimpleJobLauncher();
|
||||
SimpleJobLauncher launcher = new SimpleJobLauncher();
|
||||
|
||||
assertFalse(bootstrap.isRunning());
|
||||
// no exception should be thrown if stop is called on unstarted
|
||||
assertFalse(launcher.isRunning());
|
||||
// no exception should be thrown if stop is called on unran
|
||||
// container
|
||||
// this is to fullfill the contract outlined in Lifecycle#stop().
|
||||
bootstrap.stop();
|
||||
launcher.stop();
|
||||
}
|
||||
|
||||
private class InterruptibleContainer implements JobExecutorFacade {
|
||||
private class InterruptibleFacade implements JobExecutorFacade {
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.batch.container.BatchContainer#start()
|
||||
* @see org.springframework.batch.container.BatchContainer#run()
|
||||
*/
|
||||
public void start() {
|
||||
public void run() {
|
||||
try {
|
||||
// 1 seconds should be long enough to allow the thread to be
|
||||
// started and
|
||||
// for interrupt to be called;
|
||||
// run and for interrupt to be called;
|
||||
System.out.println("Facade sleep called.");
|
||||
Thread.sleep(300);
|
||||
//return ExitStatus.FAILED;
|
||||
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
// thread interrupted, allow to exit normally
|
||||
//return ExitStatus.FAILED;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void start(JobIdentifier runtimeInformation) {
|
||||
start();
|
||||
public ExitStatus start(JobIdentifier runtimeInformation) {
|
||||
run();
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
|
||||
public void stop(JobIdentifier runtimeInformation) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.batch.core.runtime.JobIdentifier;
|
||||
import org.springframework.batch.core.runtime.JobIdentifierFactory;
|
||||
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
|
||||
import org.springframework.batch.execution.JobExecutorFacade;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.interceptor.RepeatOperationsApplicationEvent;
|
||||
import org.springframework.batch.statistics.StatisticsProvider;
|
||||
import org.springframework.batch.support.PropertiesConverter;
|
||||
@@ -142,8 +143,9 @@ public class TaskExecutorJobLauncherTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void start(JobIdentifier runtimeInformation) {
|
||||
public ExitStatus start(JobIdentifier runtimeInformation) {
|
||||
start();
|
||||
return ExitStatus.FAILED;
|
||||
}
|
||||
|
||||
public void stop(JobIdentifier runtimeInformation) {
|
||||
|
||||
@@ -80,8 +80,9 @@ public class SimpleJobExecutorFacaderTests extends TestCase {
|
||||
final SimpleJobIdentifier jobRuntimeInformation = new SimpleJobIdentifier("bar");
|
||||
jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation);
|
||||
jobExecutor = new JobExecutor() {
|
||||
public void run(JobConfiguration configuration, JobExecutionContext jobExecutionContext) throws BatchCriticalException {
|
||||
public ExitStatus run(JobConfiguration configuration, JobExecutionContext jobExecutionContext) throws BatchCriticalException {
|
||||
jobExecutionContext.getJob().setIdentifier(jobRuntimeInformation);
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
};
|
||||
JobInstance job = new JobInstance();
|
||||
@@ -104,7 +105,7 @@ public class SimpleJobExecutorFacaderTests extends TestCase {
|
||||
|
||||
public void testIsRunning() throws Exception {
|
||||
simpleContainer.setJobExecutor(new JobExecutor() {
|
||||
public void run(JobConfiguration configuration, JobExecutionContext jobExecutionContext)
|
||||
public ExitStatus run(JobConfiguration configuration, JobExecutionContext jobExecutionContext)
|
||||
throws BatchCriticalException {
|
||||
while (running) {
|
||||
try {
|
||||
@@ -113,7 +114,11 @@ public class SimpleJobExecutorFacaderTests extends TestCase {
|
||||
catch (InterruptedException e) {
|
||||
throw new BatchCriticalException("Interrupted unexpectedly!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
});
|
||||
simpleContainer.setJobConfigurationLocator(new JobConfigurationLocator() {
|
||||
|
||||
@@ -241,7 +241,5 @@ public class DefaultJobExecutorTests extends TestCase {
|
||||
JobExecution jobExecution = (JobExecution) jobDao.findJobExecutions(job).get(0);
|
||||
assertEquals(job.getId(), jobExecution.getJobId());
|
||||
assertEquals(status, jobExecution.getStatus());
|
||||
int exitCode = status==BatchStatus.STOPPED || status==BatchStatus.FAILED ? -1 : 0;
|
||||
assertEquals(exitCode, jobExecution.getExitCode());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.batch.execution.step.simple;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
|
||||
/**
|
||||
@@ -42,8 +43,8 @@ public class ChunkOperationsStepConfigurationTests extends TestCase {
|
||||
*/
|
||||
public void testStepExecutorStepConfigurationTasklet() {
|
||||
Tasklet tasklet = new Tasklet() {
|
||||
public boolean execute() throws Exception {
|
||||
return false;
|
||||
public ExitStatus execute() throws Exception {
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
};
|
||||
configuration = new ChunkOperationsStepConfiguration(tasklet);
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.batch.execution.tasklet.ItemProviderProcessTasklet;
|
||||
import org.springframework.batch.item.ItemProcessor;
|
||||
import org.springframework.batch.item.ItemProvider;
|
||||
import org.springframework.batch.item.provider.ListItemProvider;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
|
||||
import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
|
||||
@@ -129,13 +130,13 @@ public class DefaultStepExecutorTests extends TestCase {
|
||||
final StepExecutionContext stepExecutionContext = new StepExecutionContext(jobExecutionContext, step);
|
||||
|
||||
stepConfiguration.setTasklet(new Tasklet() {
|
||||
public boolean execute() throws Exception {
|
||||
public ExitStatus execute() throws Exception {
|
||||
assertEquals(step, stepExecutionContext.getStep());
|
||||
assertEquals(1, jobExecutionContext.getChunkContexts().size());
|
||||
assertEquals(1, jobExecutionContext.getStepContexts().size());
|
||||
assertNotNull(StepSynchronizationManager.getContext().getJobIdentifier());
|
||||
processed.add("foo");
|
||||
return true;
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -166,7 +167,7 @@ public class DefaultStepExecutorTests extends TestCase {
|
||||
|
||||
Tasklet module = new Tasklet(){
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
public ExitStatus execute() throws Exception {
|
||||
int counter = 0;
|
||||
counter++;
|
||||
|
||||
@@ -174,7 +175,7 @@ public class DefaultStepExecutorTests extends TestCase {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
return true;
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.batch.execution.step.simple;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.exception.handler.DefaultExceptionHandler;
|
||||
|
||||
/**
|
||||
@@ -42,8 +43,8 @@ public class SimpleStepConfigurationTests extends TestCase {
|
||||
*/
|
||||
public void testSimpleStepConfigurationTasklet() {
|
||||
Tasklet tasklet = new Tasklet() {
|
||||
public boolean execute() throws Exception {
|
||||
return false;
|
||||
public ExitStatus execute() throws Exception {
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
};
|
||||
configuration = new SimpleStepConfiguration(tasklet);
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.batch.execution.repository.dao.JobDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobDao;
|
||||
import org.springframework.batch.execution.repository.dao.MapStepDao;
|
||||
import org.springframework.batch.execution.repository.dao.StepDao;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
|
||||
import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
|
||||
@@ -75,14 +76,14 @@ public class StepExecutorInterruptionTests extends TestCase {
|
||||
JobExecutionContext jobExecutionContext = new JobExecutionContext(null, new JobInstance(new Long(0)));
|
||||
final StepExecutionContext stepExecutionContext = new StepExecutionContext(jobExecutionContext, step);
|
||||
stepConfiguration.setTasklet(new Tasklet() {
|
||||
public boolean execute() throws Exception {
|
||||
public ExitStatus execute() throws Exception {
|
||||
// do something non-trivial (and not Thread.sleep())
|
||||
double foo = 1;
|
||||
for (int i = 2; i < 250; i++) {
|
||||
foo = foo * i;
|
||||
}
|
||||
// always return true, so processing always continues
|
||||
return foo != 1;
|
||||
return new ExitStatus(foo != 1);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ public class ItemProviderProcessTaskletTests extends TestCase {
|
||||
items = Collections.singletonList("foo");
|
||||
|
||||
// call execute
|
||||
assertTrue(module.execute());
|
||||
assertTrue(module.execute().isContinuable());
|
||||
|
||||
// verify method calls
|
||||
assertEquals(1, list.size());
|
||||
@@ -112,7 +112,7 @@ public class ItemProviderProcessTaskletTests extends TestCase {
|
||||
// TEST2: data provider returns null (nothing to read)
|
||||
|
||||
// call read
|
||||
assertFalse(module.execute());
|
||||
assertFalse(module.execute().isContinuable());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ CREATE TABLE BATCH_JOB_EXECUTION (
|
||||
START_TIME TIMESTAMP NOT NULL ,
|
||||
END_TIME TIMESTAMP ,
|
||||
STATUS VARCHAR(10),
|
||||
EXIT_CODE BIGINT);
|
||||
EXIT_CODE VARCHAR(250));
|
||||
|
||||
CREATE TABLE BATCH_STEP (
|
||||
ID BIGINT IDENTITY PRIMARY KEY ,
|
||||
@@ -36,7 +36,7 @@ CREATE TABLE BATCH_STEP_EXECUTION (
|
||||
COMMIT_COUNT BIGINT ,
|
||||
TASK_COUNT BIGINT ,
|
||||
TASK_STATISTICS VARCHAR(250),
|
||||
EXIT_CODE BIGINT,
|
||||
EXIT_CODE VARCHAR(250),
|
||||
EXIT_MESSAGE VARCHAR(250));
|
||||
|
||||
CREATE TABLE BATCH_STEP_EXECUTION_SEQ (
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
|
||||
|
||||
<bean id="simpleContainer" class="org.springframework.batch.execution.facade.SimpleJobExecutorFacade">
|
||||
<bean id="simpleFacade" class="org.springframework.batch.execution.facade.SimpleJobExecutorFacade">
|
||||
<property name="jobRepository" ref="simpleJobRepository" />
|
||||
<property name="jobConfigurationLocator" ref="jobConfigurationRegistry"/>
|
||||
<property name="jobExecutor" ref="jobLifecycle" />
|
||||
</bean>
|
||||
|
||||
<bean id="simpleContainerLauncher" class="org.springframework.batch.execution.bootstrap.SimpleJobLauncher">
|
||||
<property name="batchContainer" ref="simpleContainer" />
|
||||
<property name="jobRuntimeInformationFactory" ref="jobRuntimeInformationFactory"/>
|
||||
<property name="jobExecutorFacade" ref="simpleFacade" />
|
||||
<property name="jobIdentifierFactory" ref="jobRuntimeInformationFactory"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jobConfigurationRegistry" class="org.springframework.batch.execution.configuration.MapJobConfigurationRegistry"/>
|
||||
|
||||
@@ -37,20 +37,27 @@ public class ExitStatus {
|
||||
/**
|
||||
* Convenient constant value representing finished processing with an error.
|
||||
*/
|
||||
public static ExitStatus FAILED = new ExitStatus(false, -1);
|
||||
public static ExitStatus FAILED = new ExitStatus(false);
|
||||
|
||||
private final boolean continuable;
|
||||
|
||||
private final int exitCode;
|
||||
private final String exitCode;
|
||||
|
||||
private final String exitDescription;
|
||||
|
||||
public ExitStatus(boolean continuable) {
|
||||
this(continuable, 0);
|
||||
this(continuable, "", "");
|
||||
}
|
||||
|
||||
public ExitStatus(boolean continuable, int exitCode) {
|
||||
public ExitStatus(boolean continuable, String exitCode) {
|
||||
this(continuable, exitCode, "");
|
||||
}
|
||||
|
||||
public ExitStatus(boolean continuable, String exitCode, String exitDescription){
|
||||
super();
|
||||
this.continuable = continuable;
|
||||
this.exitCode = exitCode;
|
||||
this.exitDescription = exitDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,12 +73,21 @@ public class ExitStatus {
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the exit code (defaults to 0).
|
||||
* Getter for the exit code (defaults to blank).
|
||||
* @return the exit code.
|
||||
*/
|
||||
public int getExitCode() {
|
||||
public String getExitCode() {
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the exit description (defaults to blank)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getExitDescription() {
|
||||
return exitDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link ExitStatus} with a logical combination of the
|
||||
@@ -81,18 +97,7 @@ public class ExitStatus {
|
||||
* logical and of the current value and the argument provided.
|
||||
*/
|
||||
public ExitStatus and(boolean continuable) {
|
||||
return and(new ExitStatus(continuable));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link ExitStatus} with a logical combination of the
|
||||
* continuable flag and adding the other exit code.
|
||||
* @param other an other {@link ExitStatus}.
|
||||
* @return a new {@link ExitStatus} with {@link #isContinuable()} the
|
||||
* logical and of the current value and the other's.
|
||||
*/
|
||||
public ExitStatus and(ExitStatus other) {
|
||||
return new ExitStatus(this.continuable && other.isContinuable(), exitCode).addExitCode(other.getExitCode());
|
||||
return new ExitStatus(this.continuable && continuable);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -100,26 +105,8 @@ public class ExitStatus {
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "continuable=" + continuable + ";exitCode=" + exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates the existing status except that a new exit code is added as
|
||||
* per the argument. If both codes (the current and the new one provided)
|
||||
* are negative then the lower of the two is returned, otherwise the higher
|
||||
* or the two.
|
||||
*
|
||||
* @param exitCode the new value of the exitCode
|
||||
* @return a new {@link ExitStatus} instance
|
||||
*/
|
||||
public ExitStatus addExitCode(int exitCode) {
|
||||
if (this.exitCode < 0 || exitCode < 0) {
|
||||
exitCode = Math.min(this.exitCode, exitCode);
|
||||
}
|
||||
else {
|
||||
exitCode = Math.max(this.exitCode, exitCode);
|
||||
}
|
||||
return new ExitStatus(this.continuable, exitCode);
|
||||
return "continuable=" + continuable + ";exitCode=" + exitCode +
|
||||
";exitDescription=" + exitDescription;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -79,5 +79,5 @@ public interface RepeatInterceptor {
|
||||
* @param context the current batch context.
|
||||
* @return TODO
|
||||
*/
|
||||
ExitStatus close(RepeatContext context);
|
||||
void close(RepeatContext context);
|
||||
}
|
||||
|
||||
@@ -58,9 +58,10 @@ public class ApplicationEventPublisherRepeatInterceptor implements ApplicationEv
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.batch.repeat.RepeatInterceptor#close(org.springframework.batch.repeat.RepeatContext)
|
||||
*/
|
||||
public ExitStatus close(RepeatContext context) {
|
||||
public void close(RepeatContext context) {
|
||||
publish(context, "Closed repeat context with batch complete", RepeatOperationsApplicationEvent.CLOSE);
|
||||
return ExitStatus.CONTINUABLE;
|
||||
//TODO: why is this returning continuable?
|
||||
//return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -28,8 +28,7 @@ public class RepeatInterceptorAdapter implements RepeatInterceptor {
|
||||
public void after(RepeatContext context, Object result) {
|
||||
}
|
||||
|
||||
public ExitStatus close(RepeatContext context) {
|
||||
return ExitStatus.CONTINUABLE;
|
||||
public void close(RepeatContext context) {
|
||||
}
|
||||
|
||||
public void onError(RepeatContext context, Throwable e) {
|
||||
|
||||
@@ -245,7 +245,7 @@ public class RepeatTemplate implements RepeatOperations {
|
||||
try {
|
||||
for (int i = interceptors.length; i-- > 0;) {
|
||||
RepeatInterceptor interceptor = interceptors[i];
|
||||
result = result.and(interceptor.close(context));
|
||||
interceptor.close(context);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
||||
@@ -27,9 +27,9 @@ public class ExitStatusTests extends TestCase {
|
||||
* Test method for {@link org.springframework.batch.repeat.ExitStatus#ExitStatus(boolean, int)}.
|
||||
*/
|
||||
public void testExitStatusBooleanInt() {
|
||||
ExitStatus status = new ExitStatus(true, 10);
|
||||
ExitStatus status = new ExitStatus(true, "10");
|
||||
assertTrue(status.isContinuable());
|
||||
assertEquals(10, status.getExitCode());
|
||||
assertEquals("10", status.getExitCode());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,7 +38,7 @@ public class ExitStatusTests extends TestCase {
|
||||
public void testExitStatusConstantsContinuable() {
|
||||
ExitStatus status = ExitStatus.CONTINUABLE;
|
||||
assertTrue(status.isContinuable());
|
||||
assertEquals(0, status.getExitCode());
|
||||
assertEquals("", status.getExitCode());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ public class ExitStatusTests extends TestCase {
|
||||
public void testExitStatusConstantsFinished() {
|
||||
ExitStatus status = ExitStatus.FINISHED;
|
||||
assertFalse(status.isContinuable());
|
||||
assertEquals(0, status.getExitCode());
|
||||
assertEquals("", status.getExitCode());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,43 +62,8 @@ public class ExitStatusTests extends TestCase {
|
||||
* Test method for {@link org.springframework.batch.repeat.ExitStatus#and(org.springframework.batch.repeat.ExitStatus)}.
|
||||
*/
|
||||
public void testAndExitStatus() {
|
||||
assertTrue(ExitStatus.CONTINUABLE.and(ExitStatus.CONTINUABLE).isContinuable());
|
||||
assertFalse(ExitStatus.CONTINUABLE.and(ExitStatus.FINISHED).isContinuable());
|
||||
assertTrue(ExitStatus.CONTINUABLE.and(ExitStatus.CONTINUABLE.isContinuable()).isContinuable());
|
||||
assertFalse(ExitStatus.CONTINUABLE.and(ExitStatus.FINISHED.isContinuable()).isContinuable());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.repeat.ExitStatus#addExitCode(int)}.
|
||||
*/
|
||||
public void testAddExitCode() {
|
||||
ExitStatus status = ExitStatus.FINISHED.addExitCode(10);
|
||||
assertEquals(10, status.getExitCode());
|
||||
assertFalse(status.isContinuable());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.repeat.ExitStatus#addExitCode(int)}.
|
||||
*/
|
||||
public void testAddExitCodeBothNegative() {
|
||||
ExitStatus status = ExitStatus.FINISHED.addExitCode(-2);
|
||||
assertEquals(-2, status.getExitCode());
|
||||
assertEquals(-3, status.addExitCode(-3).getExitCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.repeat.ExitStatus#addExitCode(int)}.
|
||||
*/
|
||||
public void testAddExitCodeBothPositive() {
|
||||
ExitStatus status = ExitStatus.FINISHED.addExitCode(2);
|
||||
assertEquals(2, status.getExitCode());
|
||||
assertEquals(3, status.addExitCode(3).getExitCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.repeat.ExitStatus#addExitCode(int)}.
|
||||
*/
|
||||
public void testAddExitCodeNewNegative() {
|
||||
ExitStatus status = ExitStatus.FINISHED.addExitCode(2);
|
||||
assertEquals(2, status.getExitCode());
|
||||
assertEquals(-3, status.addExitCode(-3).getExitCode());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,14 +149,12 @@ public class RepeatInterceptorTests extends TestCase {
|
||||
RepeatTemplate template = new RepeatTemplate();
|
||||
final List calls = new ArrayList();
|
||||
template.setInterceptors(new RepeatInterceptor[] { new RepeatInterceptorAdapter() {
|
||||
public ExitStatus close(RepeatContext context) {
|
||||
public void close(RepeatContext context) {
|
||||
calls.add("1");
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
}, new RepeatInterceptorAdapter() {
|
||||
public ExitStatus close(RepeatContext context) {
|
||||
public void close(RepeatContext context) {
|
||||
calls.add("2");
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
} });
|
||||
template.iterate(new RepeatCallback() {
|
||||
@@ -171,32 +169,6 @@ public class RepeatInterceptorTests extends TestCase {
|
||||
assertEquals("[2, 1]", calls.toString());
|
||||
}
|
||||
|
||||
public void testCloseInterceptorsCanChangeExitCode() throws Exception {
|
||||
RepeatTemplate template = new RepeatTemplate();
|
||||
final List calls = new ArrayList();
|
||||
template.setInterceptors(new RepeatInterceptor[] { new RepeatInterceptorAdapter() {
|
||||
public ExitStatus close(RepeatContext context) {
|
||||
calls.add("1");
|
||||
return ExitStatus.FINISHED.addExitCode(1);
|
||||
}
|
||||
}, new RepeatInterceptorAdapter() {
|
||||
public ExitStatus close(RepeatContext context) {
|
||||
calls.add("2");
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
} });
|
||||
ExitStatus status = template.iterate(new RepeatCallback() {
|
||||
public ExitStatus doInIteration(RepeatContext context) throws Exception {
|
||||
count++;
|
||||
return new ExitStatus(count < 2);
|
||||
}
|
||||
});
|
||||
// Test that only one call comes in to the callback...
|
||||
assertEquals(2, count);
|
||||
// ... and the interceptor is called once.
|
||||
assertEquals("[2, 1]", calls.toString());
|
||||
assertEquals(1, status.getExitCode());
|
||||
}
|
||||
|
||||
public void testOnErrorInterceptors() throws Exception {
|
||||
RepeatTemplate template = new RepeatTemplate();
|
||||
|
||||
@@ -1 +1 @@
|
||||
<?xml version='1.0' encoding='utf-8'?><purchaseOrders xsi:schemaLocation="http://adsj.accenture.com/purchaseorders purchaseorders.xsd" xmlns="http://adsj.accenture.com/purchaseorders" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><order><customer><name>Gladys Kravitz</name><address>Anytown, PA</address><age>34</age><moo>0</moo><poo>0</poo></customer><date>2003-01-07 14:16:00.0 GMT</date><lineItems><lineItem><description>Burnham's Celestial Handbook, Vol 1</description><perUnitOunces>5.0</perUnitOunces><price>21.79</price><quantity>2</quantity></lineItem><lineItem><description>Burnham's Celestial Handbook, Vol 2</description><perUnitOunces>5.0</perUnitOunces><price>19.89</price><quantity>2</quantity></lineItem></lineItems></order><order><customer><name>John Smith</name><address>Chicago, IL</address><age>46</age><moo>0</moo><poo>0</poo></customer><date>2003-01-07 14:16:02.0 GMT</date><lineItems><lineItem><description>XmlBeans in Action</description><perUnitOunces>3.0</perUnitOunces><price>41.29</price><quantity>1</quantity></lineItem><lineItem><description>JSR-173</description><perUnitOunces>1.0</perUnitOunces><price>11.99</price><quantity>5</quantity></lineItem><lineItem><description>Teach Yourself XML in 21 days</description><perUnitOunces>1.0</perUnitOunces><price>35.49</price><quantity>1</quantity></lineItem></lineItems></order><order><customer><name>Peter Newman</name><address>Cleveland, OH</address><age>23</age><moo>0</moo><poo>0</poo></customer><date>2003-01-07 14:16:35.0 GMT</date><lineItems><lineItem><description>Java 6</description><perUnitOunces>2.0</perUnitOunces><price>12.79</price><quantity>3</quantity></lineItem></lineItems></order></purchaseOrders>
|
||||
<?xml version='1.0' encoding='utf-8'?><purchaseOrders xsi:schemaLocation="http://adsj.accenture.com/purchaseorders purchaseorders.xsd" xmlns="http://adsj.accenture.com/purchaseorders" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><order><customer><name>Gladys Kravitz</name><address>Anytown, PA</address><age>34</age><moo>0</moo><poo>0</poo></customer><date>2003-01-07 08:16:00.0 CST</date><lineItems><lineItem><description>Burnham's Celestial Handbook, Vol 1</description><perUnitOunces>5.0</perUnitOunces><price>21.79</price><quantity>2</quantity></lineItem><lineItem><description>Burnham's Celestial Handbook, Vol 2</description><perUnitOunces>5.0</perUnitOunces><price>19.89</price><quantity>2</quantity></lineItem></lineItems></order><order><customer><name>John Smith</name><address>Chicago, IL</address><age>46</age><moo>0</moo><poo>0</poo></customer><date>2003-01-07 08:16:02.0 CST</date><lineItems><lineItem><description>XmlBeans in Action</description><perUnitOunces>3.0</perUnitOunces><price>41.29</price><quantity>1</quantity></lineItem><lineItem><description>JSR-173</description><perUnitOunces>1.0</perUnitOunces><price>11.99</price><quantity>5</quantity></lineItem><lineItem><description>Teach Yourself XML in 21 days</description><perUnitOunces>1.0</perUnitOunces><price>35.49</price><quantity>1</quantity></lineItem></lineItems></order><order><customer><name>Peter Newman</name><address>Cleveland, OH</address><age>23</age><moo>0</moo><poo>0</poo></customer><date>2003-01-07 08:16:35.0 CST</date><lineItems><lineItem><description>Java 6</description><perUnitOunces>2.0</perUnitOunces><price>12.79</price><quantity>3</quantity></lineItem></lineItems></order></purchaseOrders>
|
||||
@@ -20,6 +20,7 @@ package org.springframework.batch.sample.module;
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.execution.tasklet.RestartableItemProviderTasklet;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* Hacked {@link Tasklet} that throws exception on a given record number
|
||||
@@ -36,7 +37,7 @@ public class ExceptionRestartableTasklet extends RestartableItemProviderTasklet
|
||||
/* (non-Javadoc)
|
||||
* @see Tasklet#execute()
|
||||
*/
|
||||
public boolean execute() throws Exception {
|
||||
public ExitStatus execute() throws Exception {
|
||||
|
||||
counter++;
|
||||
if (counter == throwExceptionOnRecordNumber) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.batch.sample.module;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.statistics.StatisticsProvider;
|
||||
import org.springframework.batch.support.PropertiesConverter;
|
||||
|
||||
@@ -41,10 +42,10 @@ public class InfiniteLoopTasklet implements Tasklet, StatisticsProvider {
|
||||
super();
|
||||
}
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
public ExitStatus execute() throws Exception {
|
||||
Thread.sleep(500);
|
||||
count++;
|
||||
return true;
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="batchContainer" class="org.springframework.batch.execution.facade.SimpleJobExecutorFacade">
|
||||
<bean id="jobExecutorFacade" class="org.springframework.batch.execution.facade.SimpleJobExecutorFacade">
|
||||
<property name="jobRepository" ref="simpleJobRepository" />
|
||||
<property name="jobConfigurationLocator" ref="jobConfigurationRegistry"/>
|
||||
<property name="jobExecutor" ref="jobExecutor" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.batch.execution.bootstrap.SimpleJobLauncher">
|
||||
<property name="batchContainer" ref="batchContainer" />
|
||||
<property name="jobExecutorFacade" ref="jobExecutorFacade" />
|
||||
</bean>
|
||||
|
||||
<bean id="jobConfigurationRegistry" class="org.springframework.batch.execution.configuration.MapJobConfigurationRegistry"/>
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.batch.sample;
|
||||
|
||||
import org.springframework.batch.core.configuration.JobConfiguration;
|
||||
import org.springframework.batch.execution.bootstrap.JobLauncher;
|
||||
import org.springframework.batch.execution.bootstrap.SynchronousJobLauncher;
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
|
||||
/**
|
||||
@@ -25,7 +26,7 @@ import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
*/
|
||||
public abstract class AbstractBatchLauncherTests extends AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
protected JobLauncher launcher;
|
||||
protected SynchronousJobLauncher launcher;
|
||||
private JobConfiguration jobConfiguration;
|
||||
|
||||
/**
|
||||
@@ -36,7 +37,7 @@ public abstract class AbstractBatchLauncherTests extends AbstractDependencyInjec
|
||||
return jobConfiguration.getName();
|
||||
}
|
||||
|
||||
public void setBatchContainerLauncher(JobLauncher launcher) {
|
||||
public void setBatchContainerLauncher(SynchronousJobLauncher launcher) {
|
||||
this.launcher = launcher;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public abstract class AbstractLifecycleSpringContextTests extends AbstractBatchL
|
||||
|
||||
public void testLifecycle() throws Exception {
|
||||
validatePreConditions();
|
||||
launcher.start(getJobName());
|
||||
launcher.run(getJobName());
|
||||
launcher.stop();
|
||||
validatePostConditions();
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class GracefulShutdownFunctionalTest extends AbstractBatchLauncherTests {
|
||||
Thread jobThread = new Thread(){
|
||||
public void run(){
|
||||
try {
|
||||
launcher.start(getJobName());
|
||||
launcher.run(getJobName());
|
||||
}
|
||||
catch (RepeatException e) {
|
||||
if (!(e.getCause() instanceof InterruptedException)) {
|
||||
|
||||
@@ -81,7 +81,7 @@ public class RestartFunctionalTests extends AbstractBatchLauncherTests {
|
||||
|
||||
// load the application context and launch the job
|
||||
private void runJob() throws Exception, Exception {
|
||||
launcher.start(getJobName());
|
||||
launcher.run(getJobName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user