diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/bootstrap/support/BatchCommandLineLauncher.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/bootstrap/support/SimpleCommandLineJobDispatcher.java
similarity index 66%
rename from spring-batch-execution/src/main/java/org/springframework/batch/execution/bootstrap/support/BatchCommandLineLauncher.java
rename to spring-batch-execution/src/main/java/org/springframework/batch/execution/bootstrap/support/SimpleCommandLineJobDispatcher.java
index d4f380c3e..11c3ef5da 100644
--- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/bootstrap/support/BatchCommandLineLauncher.java
+++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/bootstrap/support/SimpleCommandLineJobDispatcher.java
@@ -36,7 +36,7 @@ import org.springframework.util.Assert;
/**
*
- * Basic Launcher for starting jobs from the command line. In general, it is
+ * Basic launcher for starting jobs from the command line. In general, it is
* assumed that this launcher will primarily be used to start a job via a script
* from an Enterprise Scheduler. Therefore, exit codes are mapped to integers so
* that schedulers can use the returned values to determine the next course of
@@ -48,19 +48,16 @@ import org.springframework.util.Assert;
*
*
*
- * With any launch of a batch job within Spring Batch, a minimum of two contexts
- * must be loaded. One is the context containing the Job, the other contains the
- * 'Execution Environment'. That is, the JobExecutorFacade (which contains all
- * the executors, plus the repository), the JobIdentifierFactory, and a normal
- * JobLauncher. This command line launcher loads these application contexts by
- * first loading the execution environment context via a
- * {@link ContextSingletonBeanFactoryLocator}, which will search for the
- * default key from classpath*:beanRefContext.xml to return the context. This
- * will then be used as the parent to the Job context. All required dependencies
- * of the launcher will then be satisfied by autowiring by type from the
- * combined application context. Default values are provided for all fields
- * except the JobLauncher. Therefore, if autowiring fails to set it (it should
- * be noted that dependency checking is disabled because most of the fields have
+ * With any launch of a batch job within Spring Batch, a Spring context
+ * containing the Job and the 'Execution Environment' has to be created. This
+ * command line launcher can be used to load that context from a single
+ * location. It can also be used to first load the execution environment context
+ * via a {@link ContextSingletonBeanFactoryLocator}. This will then be used as
+ * the parent to the Job context. All required dependencies of the launcher will
+ * then be satisfied by autowiring by type from the combined application
+ * context. Default values are provided for all fields except the
+ * {@link JobLauncher}. Therefore, if autowiring fails to set it (it should be
+ * noted that dependency checking is disabled because most of the fields have
* default values and thus don't require dependencies to be fulfilled via
* autowiring) then an exception will be thrown. It should also be noted that
* even if an exception is thrown by this class, it will be mapped to an integer
@@ -68,54 +65,39 @@ import org.springframework.util.Assert;
*
*
*
- * One odd field might be noticed in the launcher, SystemExiter. This class is
- * used to exit from the main method, rather than calling System.exit directly.
- * This is because unit testing a class the calls System.exit() is impossible
- * without kicking off the test within a new Jvm, which it is possible to do,
- * however it is a complex solution, much more so than strategizing the exiter.
+ * Notice a property is available to set the {@link SystemExiter}. This class
+ * is used to exit from the main method, rather than calling System.exit()
+ * directly. This is because unit testing a class the calls System.exit() is
+ * impossible without kicking off the test within a new Jvm, which it is
+ * possible to do, however it is a complex solution, much more so than
+ * strategizing the exiter.
*
*
*
* VM Arguments vs. Program arguments: Because all of the arguments to the main
- * method are optional, VM arguments are used:
- *
- *
- * - -Djob.configuration.path: the classpath location of the Job to use
- *
- -Djob.name: job name to be passed to the {@link JobLauncher}
- *
- -Dbatch.execution.environment.key: the key in beanRefContext.xml used to
- * load the execution envrionement.
- *
+ * method are optional, System properties (VM arguments) are used (@see
+ * {@link #main(String[])}).
*
* @author Dave Syer
* @author Lucas Ward
* @since 2.1
*/
-public class BatchCommandLineLauncher {
+public class SimpleCommandLineJobDispatcher {
- protected static final Log logger = LogFactory.getLog(BatchCommandLineLauncher.class);
-
- /**
- * The default key for the parent context.
- */
- public static final String DEFAULT_PARENT_KEY = "batchExecutionEnvironment";
+ protected static final Log logger = LogFactory.getLog(SimpleCommandLineJobDispatcher.class);
/**
* The default path to the job configuration.
*/
public static final String DEFAULT_JOB_CONFIGURATION_PATH = "job-configuration.xml";
- /**
- * The default path to the bean reference context.
- */
- public static final String DEFAULT_BEAN_REF_CONTEXT_PATH = "beanRefContext.xml";
+ public static final String JOB_CONFIGURATION_PATH_KEY = "job.configuration.path";
- private static final String JOB_CONFIGURATION_PATH_KEY = "job.configuration.path";
+ public static final String JOB_NAME_KEY = "job.name";
- private static final String JOB_NAME_KEY = "job.name";
+ public static final String BATCH_EXECUTION_ENVIRONMENT_KEY = "batch.execution.environment.key";
- private static final String BATCH_EXECUTION_ENVIRONMENT_KEY = "batch.execution.environment.key";
-
- private static final String BEAN_REF_CONTEXT_KEY = "bean.ref.context";
+ public static final String BEAN_REF_CONTEXT_KEY = "bean.ref.context";
private JobIdentifierFactory jobIdentifierFactory = new ScheduledJobIdentifierFactory();
@@ -131,10 +113,13 @@ public class BatchCommandLineLauncher {
private String defaultJobName;
- public BatchCommandLineLauncher(String beanRefContextPath) {
+ public SimpleCommandLineJobDispatcher(String beanRefContextPath) {
+ if (beanRefContextPath == null) {
+ return;
+ }
beanFactoryLocator = ContextSingletonBeanFactoryLocator.getInstance(beanRefContextPath);
}
-
+
/**
* Setter for the name of the {@link Job} that this launcher will run.
*
@@ -213,11 +198,14 @@ public class BatchCommandLineLauncher {
ClassPathXmlApplicationContext context = null;
try {
- ConfigurableApplicationContext parent = (ConfigurableApplicationContext) beanFactoryLocator.useBeanFactory(
- parentKey).getFactory();
+ ConfigurableApplicationContext parent = null;
- parent.getAutowireCapableBeanFactory().autowireBeanProperties(this,
- AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
+ if (beanFactoryLocator != null) {
+ parent = (ConfigurableApplicationContext) beanFactoryLocator.useBeanFactory(parentKey).getFactory();
+
+ parent.getAutowireCapableBeanFactory().autowireBeanProperties(this,
+ AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
+ }
if (!path.endsWith(".xml")) {
path = path + ".xml";
@@ -234,12 +222,12 @@ public class BatchCommandLineLauncher {
if (jobName == null) {
String[] names = context.getBeanNamesForType(Job.class);
- if (names.length==1) {
+ if (names.length == 1) {
Job job = (Job) context.getBean(names[0]);
jobName = job.getName();
}
}
-
+
if (jobName == null) {
jobName = defaultJobName;
}
@@ -275,12 +263,12 @@ public class BatchCommandLineLauncher {
}
/**
- * Launch a batch job using a {@link BatchCommandLineLauncher}. Creates a
- * new Spring context for the job execution, and uses a common parent for
- * all such contexts. No exception are thrown from this method, rather
- * exceptions are logged and an integer returned through the exit status in
- * a {@link JvmSystemExiter} (which can be overridden by defining one in the
- * Spring context).
+ * Launch a batch job using a {@link SimpleCommandLineJobDispatcher}.
+ * Creates a new Spring context for the job execution, and uses a common
+ * parent for all such contexts. No exception are thrown from this method,
+ * rather exceptions are logged and an integer returned through the exit
+ * status in a {@link JvmSystemExiter} (which can be overridden by defining
+ * one in the Spring context).
*
* @param args
*
@@ -288,18 +276,24 @@ public class BatchCommandLineLauncher {
* JobConfiguration to use
* - -Djob.name: job name to be passed to the {@link JobLauncher}
*
- -Dbatch.execution.environment.key: the key in beanRefContext.xml
- * used to load the execution envrionment.
- *
- -Dbean.ref.context: an altrernative location for beanRefContext.xml.
+ * used to load the execution environment (mandatory if bean.ref.context is
+ * specified).
+ * - -Dbean.ref.context: an alternative location for beanRefContext.xml
+ * (optional, default is to only use the context specified in the
+ * job.configuration.path).
*
*/
public static void main(String[] args) {
String path = System.getProperty(JOB_CONFIGURATION_PATH_KEY, DEFAULT_JOB_CONFIGURATION_PATH);
String name = System.getProperty(JOB_NAME_KEY);
- String beanRefContextPath = System.getProperty(BEAN_REF_CONTEXT_KEY, DEFAULT_BEAN_REF_CONTEXT_PATH);
- String parentKey = System.getProperty(BATCH_EXECUTION_ENVIRONMENT_KEY, DEFAULT_PARENT_KEY);
+ String beanRefContextPath = System.getProperty(BEAN_REF_CONTEXT_KEY);
+ String parentKey = System.getProperty(BATCH_EXECUTION_ENVIRONMENT_KEY);
- BatchCommandLineLauncher command = new BatchCommandLineLauncher(beanRefContextPath);
+ Assert.state(!(beanRefContextPath == null && parentKey != null), "If you specify the "
+ + BATCH_EXECUTION_ENVIRONMENT_KEY + " you must also specify a path for the " + BEAN_REF_CONTEXT_KEY);
+
+ SimpleCommandLineJobDispatcher command = new SimpleCommandLineJobDispatcher(beanRefContextPath);
int result = command.start(path, name, parentKey);
command.exit(result);
}
diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/bootstrap/support/BatchCommandLineLauncherTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/bootstrap/support/SimpleCommandLineJobDispatcherTests.java
similarity index 63%
rename from spring-batch-execution/src/test/java/org/springframework/batch/execution/bootstrap/support/BatchCommandLineLauncherTests.java
rename to spring-batch-execution/src/test/java/org/springframework/batch/execution/bootstrap/support/SimpleCommandLineJobDispatcherTests.java
index 560a4c7f7..813d72524 100644
--- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/bootstrap/support/BatchCommandLineLauncherTests.java
+++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/bootstrap/support/SimpleCommandLineJobDispatcherTests.java
@@ -26,19 +26,22 @@ import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.util.ClassUtils;
/**
* @author Dave Syer
*
*/
-public class BatchCommandLineLauncherTests extends TestCase {
+public class SimpleCommandLineJobDispatcherTests extends TestCase {
- private static final String JOB_CONFIGURATION_PATH_KEY = "job.configuration.path";
- private static final String JOB_NAME_KEY = "job.name";
- private static final String BATCH_EXECUTION_ENVIRONMENT_KEY = "batch.execution.environment.key";
+ private static final String JOB_CONFIGURATION_PATH_KEY = SimpleCommandLineJobDispatcher.JOB_CONFIGURATION_PATH_KEY;
+ private static final String JOB_NAME_KEY = SimpleCommandLineJobDispatcher.JOB_NAME_KEY;
+ private static final String BATCH_EXECUTION_ENVIRONMENT_KEY = SimpleCommandLineJobDispatcher.BATCH_EXECUTION_ENVIRONMENT_KEY;
+ private static final String BEAN_REF_CONTEXT_KEY = SimpleCommandLineJobDispatcher.BEAN_REF_CONTEXT_KEY;
private static final String TEST_BATCH_ENVIRONMENT_KEY = "testBatchEnvironment";
private static final String TEST_BATCH_ENVIRONMENT_NO_LAUNCHER_KEY = "testBatchEnvironmentNoLauncher";
+ private static final String TEST_JOB_CONFIGURATION_WITH_ENVIRONMENT = ClassUtils.addResourcePathToPackagePath(SimpleCommandLineJobDispatcherTests.class, "test-batch-environment-with-job.xml");
BeanFactoryLocator beanFactoryLocator = ContextSingletonBeanFactoryLocator
.getInstance();
@@ -50,6 +53,8 @@ public class BatchCommandLineLauncherTests extends TestCase {
super.setUp();
System.setProperty(BATCH_EXECUTION_ENVIRONMENT_KEY,
TEST_BATCH_ENVIRONMENT_KEY);
+ System.setProperty(BEAN_REF_CONTEXT_KEY,
+ "beanRefContext.xml");
}
protected void tearDown() throws Exception {
@@ -57,6 +62,7 @@ public class BatchCommandLineLauncherTests extends TestCase {
System.clearProperty(JOB_CONFIGURATION_PATH_KEY);
System.clearProperty(JOB_NAME_KEY);
System.clearProperty(BATCH_EXECUTION_ENVIRONMENT_KEY);
+ System.clearProperty(BEAN_REF_CONTEXT_KEY);
}
public void testParentWithNoLauncher() {
@@ -66,7 +72,7 @@ public class BatchCommandLineLauncherTests extends TestCase {
System.setProperty(BATCH_EXECUTION_ENVIRONMENT_KEY,
TEST_BATCH_ENVIRONMENT_NO_LAUNCHER_KEY);
- BatchCommandLineLauncher.main(new String[0]);
+ SimpleCommandLineJobDispatcher.main(new String[0]);
assertEquals(ExitCodeMapper.JVM_EXITCODE_GENERIC_ERROR, systemExiter
.getStatus());
@@ -74,7 +80,41 @@ public class BatchCommandLineLauncherTests extends TestCase {
/**
* Test method for
- * {@link org.springframework.batch.execution.bootstrap.support.BatchCommandLineLauncher#main(java.lang.String[])}.
+ * {@link org.springframework.batch.execution.bootstrap.support.SimpleCommandLineJobDispatcher#main(java.lang.String[])}.
+ *
+ * @throws Exception
+ */
+ public void testNoBeanRefContext() throws Exception {
+ // No error, so we assume it has worked!
+ System.clearProperty(BATCH_EXECUTION_ENVIRONMENT_KEY);
+ System.clearProperty(BEAN_REF_CONTEXT_KEY);
+ System.setProperty(JOB_CONFIGURATION_PATH_KEY, TEST_JOB_CONFIGURATION_WITH_ENVIRONMENT);
+ SimpleCommandLineJobDispatcher.main(new String[0]);
+ }
+
+ /**
+ * Test method for
+ * {@link org.springframework.batch.execution.bootstrap.support.SimpleCommandLineJobDispatcher#main(java.lang.String[])}.
+ *
+ * @throws Exception
+ */
+ public void testBeanRefContextButNoEnvironment() throws Exception {
+ // No error, so we assume it has worked!
+ System.clearProperty(BEAN_REF_CONTEXT_KEY);
+ System.setProperty(JOB_CONFIGURATION_PATH_KEY, TEST_JOB_CONFIGURATION_WITH_ENVIRONMENT);
+ try {
+ SimpleCommandLineJobDispatcher.main(new String[0]);
+ } catch (IllegalStateException e) {
+ // expected
+ String message = e.getMessage();
+ assertTrue("Message should contain invalid property names:"+message, message.indexOf(SimpleCommandLineJobDispatcher.BATCH_EXECUTION_ENVIRONMENT_KEY)>=0);
+ assertTrue("Message should contain invalid property names:"+message, message.indexOf(SimpleCommandLineJobDispatcher.BEAN_REF_CONTEXT_KEY)>=0);
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.springframework.batch.execution.bootstrap.support.SimpleCommandLineJobDispatcher#main(java.lang.String[])}.
*
* @throws Exception
*/
@@ -86,7 +126,7 @@ public class BatchCommandLineLauncherTests extends TestCase {
setReturnValue(ExitStatus.FINISHED);
- BatchCommandLineLauncher.main(new String[0]);
+ SimpleCommandLineJobDispatcher.main(new String[0]);
assertEquals(ExitCodeMapper.JVM_EXITCODE_COMPLETED, systemExiter
.getStatus());
@@ -96,7 +136,7 @@ public class BatchCommandLineLauncherTests extends TestCase {
/**
* Test method for
- * {@link org.springframework.batch.execution.bootstrap.support.BatchCommandLineLauncher#main(java.lang.String[])}.
+ * {@link org.springframework.batch.execution.bootstrap.support.SimpleCommandLineJobDispatcher#main(java.lang.String[])}.
*
* @throws Exception
*/
@@ -108,7 +148,7 @@ public class BatchCommandLineLauncherTests extends TestCase {
setReturnValue(ExitStatus.FINISHED);
System.setProperty(JOB_NAME_KEY, "foo");
- BatchCommandLineLauncher.main(new String[0]);
+ SimpleCommandLineJobDispatcher.main(new String[0]);
assertEquals(ExitCodeMapper.JVM_EXITCODE_COMPLETED, systemExiter
.getStatus());
@@ -124,7 +164,7 @@ public class BatchCommandLineLauncherTests extends TestCase {
/**
* Test method for
- * {@link org.springframework.batch.execution.bootstrap.support.BatchCommandLineLauncher#main(java.lang.String[])}.
+ * {@link org.springframework.batch.execution.bootstrap.support.SimpleCommandLineJobDispatcher#main(java.lang.String[])}.
*
* @throws Exception
*/
@@ -132,17 +172,17 @@ public class BatchCommandLineLauncherTests extends TestCase {
// We can only test this without running the whole test in another jvm
// by using a special SystemExiter in the default configuration because
// otherwise it calls System.exit() by default.
- BatchCommandLineLauncher.main(new String[0]);
+ SimpleCommandLineJobDispatcher.main(new String[0]);
}
public void testInvalidJobConfig() {
// To test this without kicking off in a new jvm, we have to autowire
// the launcher (in BatchCommandLineLauncher.start) from the parent,
// *then* the child context.
- buildContext(BatchCommandLineLauncher.DEFAULT_PARENT_KEY);
+ buildContext("batchExecutionEnvironment");
assertNotNull(systemExiter);
System.setProperty(JOB_CONFIGURATION_PATH_KEY, "foo");
- BatchCommandLineLauncher.main(new String[0]);
+ SimpleCommandLineJobDispatcher.main(new String[0]);
}
private void buildContext(String key) {
diff --git a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment-no-launcher.xml b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment-no-launcher.xml
index b4e8474ed..adf314f6d 100644
--- a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment-no-launcher.xml
+++ b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment-no-launcher.xml
@@ -12,6 +12,6 @@
+ class="org.springframework.batch.execution.bootstrap.support.SimpleCommandLineJobDispatcherTests$StubSystemExiter" />
diff --git a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment-with-job.xml b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment-with-job.xml
new file mode 100644
index 000000000..ecaa727ea
--- /dev/null
+++ b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment-with-job.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment.xml b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment.xml
index cf59d0a77..238809664 100644
--- a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment.xml
+++ b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/bootstrap/support/test-batch-environment.xml
@@ -14,6 +14,6 @@
+ class="org.springframework.batch.execution.bootstrap.support.SimpleCommandLineJobDispatcherTests$StubSystemExiter" />
diff --git a/spring-batch-execution/src/test/resources/simple-container-definition.xml b/spring-batch-execution/src/test/resources/simple-container-definition.xml
index 537b99e69..d70698fd1 100644
--- a/spring-batch-execution/src/test/resources/simple-container-definition.xml
+++ b/spring-batch-execution/src/test/resources/simple-container-definition.xml
@@ -113,6 +113,6 @@
+ class="org.springframework.batch.execution.bootstrap.support.SimpleCommandLineJobDispatcherTests$StubSystemExiter" />