params) throws Exception {
+ logger.info("Unbinding JobFactory: " + jobFactory.getJobName());
+ jobRegistry.unregister(jobFactory.getJobName());
+ }
+
+}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/OsgiBundleXmlApplicationContextFactory.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/OsgiBundleXmlApplicationContextFactory.java
new file mode 100644
index 000000000..9a927d845
--- /dev/null
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/OsgiBundleXmlApplicationContextFactory.java
@@ -0,0 +1,74 @@
+package org.springframework.batch.core.configuration.support;
+
+import org.osgi.framework.BundleContext;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.osgi.context.BundleContextAware;
+import org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext;
+
+public class OsgiBundleXmlApplicationContextFactory implements BundleContextAware,
+ ApplicationContextFactory, ApplicationContextAware {
+
+ private BundleContext bundleContext;
+
+ private ApplicationContext parent;
+
+ private String path;
+
+ private String displayName;
+
+ /**
+ * @param path
+ * the resource path to the xml to load for the child context.
+ */
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ /**
+ * @param displayName the display name for the application context created.
+ */
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ /**
+ * Setter for the parent application context.
+ *
+ * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
+ */
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ parent = applicationContext;
+ }
+
+ /**
+ * Stash the {@link BundleContext} for creating a job application context
+ * later.
+ *
+ * @see org.springframework.osgi.context.BundleContextAware#setBundleContext(org.osgi.framework.BundleContext)
+ */
+ public void setBundleContext(BundleContext context) {
+ this.bundleContext = context;
+ }
+
+ /**
+ * Create an application context from the provided path, using the current
+ * OSGi {@link BundleContext} and the enclosing Spring
+ * {@link ApplicationContext} as a parent context.
+ *
+ * @see ApplicationContextFactory#createApplicationContext()
+ */
+ public ConfigurableApplicationContext createApplicationContext() {
+ OsgiBundleXmlApplicationContext context = new OsgiBundleXmlApplicationContext(
+ new String[] { path }, parent);
+ String displayName = bundleContext.getBundle().getSymbolicName() + ":" + this.displayName;
+ context.setDisplayName(displayName);
+ context.setBundleContext(bundleContext);
+ context.refresh();
+ return context;
+ }
+
+}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/CommandLineJobRunner.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/CommandLineJobRunner.java
index 7d0648e1c..5b2d009cc 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/CommandLineJobRunner.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/CommandLineJobRunner.java
@@ -48,17 +48,16 @@ import org.springframework.util.StringUtils;
*
*
* 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 load the job as well All 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} and {@link JobLocator}. 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 and returned.
+ * containing the {@link Job} and some execution context has to be created. This
+ * command line launcher can be used to load the job and its context from a
+ * single location. All 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} and {@link JobLocator}.
+ * 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 and returned.
*
*
*
@@ -89,7 +88,7 @@ import org.springframework.util.StringUtils;
*
*
*
- * The combined application context must only contain one instance of a
+ * The combined application context must contain only one instance of
* {@link JobLauncher}. The job parameters passed in to the command line will
* be converted to {@link Properties} by assuming that each individual element
* is one parameter that is separated by an equals sign. For example,
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobRegistryBackgroundJobRunner.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobRegistryBackgroundJobRunner.java
new file mode 100644
index 000000000..038b2a1a3
--- /dev/null
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/JobRegistryBackgroundJobRunner.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2006-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.batch.core.launch.support;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.batch.core.Job;
+import org.springframework.batch.core.configuration.JobFactory;
+import org.springframework.batch.core.configuration.JobRegistry;
+import org.springframework.batch.core.configuration.support.ApplicationContextJobFactory;
+import org.springframework.batch.core.configuration.support.ClassPathXmlApplicationContextFactory;
+import org.springframework.batch.core.launch.JobLauncher;
+import org.springframework.batch.core.repository.DuplicateJobException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.xml.XmlBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.util.Assert;
+
+/**
+ *
+ * Command line launcher for registering jobs with a {@link JobRegistry}.
+ * Normally this will be used in conjunction with an external trigger for the
+ * jobs registered, e.g. a JMX MBean wrapper for a {@link JobLauncher}, or a
+ * Quartz trigger.
+ *
+ *
+ *
+ * With any launch of a batch job within Spring Batch, a Spring context
+ * containing the {@link Job} has to be created. Using this launcher, the jobs
+ * are all registered with a {@link JobRegistry} defined in a parent application
+ * context. The jobs are then set up in child contexts. All dependencies of the
+ * runner will then be satisfied by autowiring by type from the parent
+ * application context. Default values are provided for all fields except the
+ * {@link JobRegistry}. Therefore, if autowiring fails to set it then an
+ * exception will be thrown.
+ *
+ *
+ * @author Dave Syer
+ *
+ */
+public class JobRegistryBackgroundJobRunner implements ResourceLoaderAware {
+
+ /**
+ * System property key that switches the runner to "embedded" mode
+ * (returning immediately from the main method). Useful for testing
+ * purposes.
+ */
+ public static final String EMBEDDED = JobRegistryBackgroundJobRunner.class.getSimpleName() + ".EMBEDDED";
+
+ private static Log logger = LogFactory.getLog(JobRegistryBackgroundJobRunner.class);
+
+ private JobRegistry registry;
+
+ private ResourceLoader resourceLoader;
+
+ private ApplicationContext parentContext = null;
+
+ final private String parentContextPath;
+
+ private static List errors = new ArrayList();
+
+ /**
+ * @param parentContextPath
+ */
+ public JobRegistryBackgroundJobRunner(String parentContextPath) {
+ super();
+ this.parentContextPath = parentContextPath;
+ }
+
+ /**
+ * Public setter for the {@link JobRegistry}.
+ * @param registry the registry to set
+ */
+ public void setRegistry(JobRegistry registry) {
+ this.registry = registry;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader)
+ */
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+
+ /**
+ * Public getter for the startup errors encountered during parent context
+ * creation.
+ * @return the errors
+ */
+ public static List getErrors() {
+ return errors;
+ }
+
+ private void register(String[] paths) throws DuplicateJobException {
+ for (int i = 0; i < paths.length; i++) {
+ String path = paths[i];
+ logger.info("Registering Job definitions from " + path);
+ ConfigurableListableBeanFactory beanFactory = new XmlBeanFactory(resourceLoader.getResource(path),
+ parentContext.getAutowireCapableBeanFactory());
+ String[] names = beanFactory.getBeanNamesForType(Job.class);
+ for (int j = 0; j < names.length; j++) {
+ ClassPathXmlApplicationContextFactory factory = new ClassPathXmlApplicationContextFactory();
+ factory.setApplicationContext(parentContext);
+ factory.setPath(path);
+ logger.info("Registering Job definition: " + names[j]);
+ registry.register(new ApplicationContextJobFactory(factory, names[j]));
+ }
+ }
+ }
+
+ /**
+ * Supply a list of application context locations, starting with the parent
+ * context, and followed by the children. The parent must contain a
+ * {@link JobRegistry} and the child contexts are expected to contain
+ * {@link Job} definitions, each of which will be registered wit the
+ * registry.
+ *
+ * Example usage:
+ *
+ *
+ * $ java -classpath ... JobRegistryBackgroundJobRunner job-registry-context.xml job1.xml job2.xml ...
+ *
+ *
+ * The child contexts are created only when needed though the
+ * {@link JobFactory} interface (but the XML is validated on startup by
+ * using it to create a {@link BeanFactory} which is then discarded).
+ *
+ * The parent context is created in a separate thread, and the program will
+ * pause for input in an infinite loop until the user hits any key.
+ *
+ * @param args the context locations to use (first one is for parent)
+ * @throws Exception if anything goes wrong with the context creation
+ */
+ public static void main(String... args) throws Exception {
+
+ Assert.state(args.length >= 1, "At least one argument (the parent context path) must be provided.");
+
+ final JobRegistryBackgroundJobRunner launcher = new JobRegistryBackgroundJobRunner(args[0]);
+ errors.clear();
+
+ logger.info("Starting job registry in parent context from XML at: [" + args[0] + "]");
+
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ launcher.run();
+ }
+ catch (RuntimeException e) {
+ errors.add(e);
+ throw e;
+ }
+ };
+ }).start();
+
+ logger.info("Waiting for parent context to start.");
+ while (launcher.parentContext == null && errors.isEmpty()) {
+ Thread.sleep(100L);
+ }
+ if (!errors.isEmpty()) {
+ logger.info(errors.size() + " errors detected on startup of parent context. Rethrowing.");
+ throw errors.get(0);
+ }
+
+ // Paths to individual job configurations.
+ final String[] paths = new String[args.length - 1];
+ System.arraycopy(args, 1, paths, 0, paths.length);
+
+ logger.info("Parent context started. Registering jobs from paths: " + Arrays.asList(paths));
+ launcher.register(paths);
+
+ if (System.getProperty(EMBEDDED) != null) {
+ return;
+ }
+
+ System.out.println("Started application. Hit any key to exit.");
+ System.in.read();
+
+ }
+
+ private void run() {
+ final ApplicationContext parent = new ClassPathXmlApplicationContext(parentContextPath);
+ parent.getAutowireCapableBeanFactory().autowireBeanProperties(this,
+ AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
+ parent.getAutowireCapableBeanFactory().initializeBean(this, getClass().getSimpleName());
+ this.parentContext = parent;
+ }
+
+}
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/ApplicationContextJobFactoryTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/ApplicationContextJobFactoryTests.java
new file mode 100644
index 000000000..0a8a1d0cf
--- /dev/null
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/ApplicationContextJobFactoryTests.java
@@ -0,0 +1,30 @@
+package org.springframework.batch.core.configuration.support;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+import org.springframework.batch.core.job.JobSupport;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.StaticApplicationContext;
+
+public class ApplicationContextJobFactoryTests {
+
+ private ApplicationContextJobFactory factory = new ApplicationContextJobFactory(
+ new StubApplicationContextFactory(), "job");
+
+ @Test
+ public void testFactoryContext() throws Exception {
+ assertNotNull(factory.createJob());
+ }
+
+ private static class StubApplicationContextFactory implements
+ ApplicationContextFactory {
+ public ConfigurableApplicationContext createApplicationContext() {
+ StaticApplicationContext context = new StaticApplicationContext();
+ context.registerSingleton("job", JobSupport.class);
+ return context ;
+ }
+
+ }
+
+}
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/ClassPathXmlApplicationContextJobFactoryTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/ClassPathXmlApplicationContextFactoryTests.java
similarity index 56%
rename from spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/ClassPathXmlApplicationContextJobFactoryTests.java
rename to spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/ClassPathXmlApplicationContextFactoryTests.java
index ddbd02469..a69375672 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/ClassPathXmlApplicationContextJobFactoryTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/ClassPathXmlApplicationContextFactoryTests.java
@@ -17,28 +17,25 @@ package org.springframework.batch.core.configuration.support;
import junit.framework.TestCase;
+import org.springframework.batch.core.Job;
import org.springframework.util.ClassUtils;
/**
* @author Dave Syer
- *
+ *
*/
-public class ClassPathXmlApplicationContextJobFactoryTests extends TestCase {
-
- private ClassPathXmlApplicationContextJobFactory factory = new ClassPathXmlApplicationContextJobFactory("test-job", ClassUtils.addResourcePathToPackagePath(getClass(), "trivial-context.xml"));
+public class ClassPathXmlApplicationContextFactoryTests extends TestCase {
+
+ private ClassPathXmlApplicationContextFactory factory = new ClassPathXmlApplicationContextFactory();
- /**
- * Test method for {@link org.springframework.batch.core.configuration.support.ClassPathXmlApplicationContextJobFactory#createJob()}.
- */
public void testCreateJob() {
- assertNotNull(factory.createJob());
+ factory.setPath(ClassUtils.addResourcePathToPackagePath(getClass(), "trivial-context.xml"));
+ assertNotNull(factory.createApplicationContext());
}
- /**
- * Test method for {@link org.springframework.batch.core.configuration.support.ClassPathXmlApplicationContextJobFactory#getJobName()}.
- */
public void testGetJobName() {
- assertEquals("test-job", factory.getJobName());
+ factory.setPath(ClassUtils.addResourcePathToPackagePath(getClass(), "trivial-context.xml"));
+ assertEquals("test-job", factory.createApplicationContext().getBeanNamesForType(Job.class)[0]);
}
}
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobRegistryBackgroundJobRunnerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobRegistryBackgroundJobRunnerTests.java
new file mode 100644
index 000000000..4f907e081
--- /dev/null
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/JobRegistryBackgroundJobRunnerTests.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2006-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.batch.core.launch.support;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.util.ClassUtils;
+
+/**
+ * @author Dave Syer
+ *
+ */
+public class JobRegistryBackgroundJobRunnerTests {
+
+ /**
+ * Test method for
+ * {@link org.springframework.batch.core.launch.support.JobRegistryBackgroundJobRunner#main(java.lang.String[])}.
+ */
+ @Test
+ public void testMain() {
+ assertEquals(0, JobRegistryBackgroundJobRunner.getErrors().size());
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ JobRegistryBackgroundJobRunner.getErrors().clear();
+ System.setProperty(JobRegistryBackgroundJobRunner.EMBEDDED, "");
+ JobRegistryBackgroundJobRunner.main(
+ ClassUtils.addResourcePathToPackagePath(getClass(), "test-environment.xml"), ClassUtils
+ .addResourcePathToPackagePath(getClass(), "job.xml"));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ System.clearProperty(JobRegistryBackgroundJobRunner.EMBEDDED);
+ JobRegistryBackgroundJobRunner.getErrors().clear();
+ }
+}
diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/test-environment.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/test-environment.xml
index 15e44a16b..d442bb315 100644
--- a/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/test-environment.xml
+++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/launch/support/test-environment.xml
@@ -1,25 +1,22 @@
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-batch-samples/.settings/jmxLauncher.launch b/spring-batch-samples/.settings/jmxLauncher.launch
index 937a244c2..6016abc33 100644
--- a/spring-batch-samples/.settings/jmxLauncher.launch
+++ b/spring-batch-samples/.settings/jmxLauncher.launch
@@ -2,7 +2,7 @@
-
+
@@ -10,7 +10,8 @@
-
+
+
diff --git a/spring-batch-samples/.settings/quartzLauncher.launch b/spring-batch-samples/.settings/quartzLauncher.launch
index bffcd4dbe..82735f801 100644
--- a/spring-batch-samples/.settings/quartzLauncher.launch
+++ b/spring-batch-samples/.settings/quartzLauncher.launch
@@ -1,8 +1,8 @@
-
+
-
+
@@ -10,6 +10,7 @@
-
+
+
diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/TaskExecutorLauncher.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/TaskExecutorLauncher.java
deleted file mode 100644
index 9aba00d09..000000000
--- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/TaskExecutorLauncher.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.batch.sample.launch;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.springframework.batch.core.Job;
-import org.springframework.batch.core.configuration.JobRegistry;
-import org.springframework.batch.core.configuration.support.ClassPathXmlApplicationContextJobFactory;
-import org.springframework.batch.core.repository.DuplicateJobException;
-import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.xml.XmlBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-import org.springframework.core.io.ResourceLoader;
-
-/**
- * @author Dave Syer
- *
- */
-public class TaskExecutorLauncher implements ResourceLoaderAware {
-
- private JobRegistry registry;
-
- private ResourceLoader resourceLoader;
-
- private ApplicationContext parentContext = null;
-
- private static List errors = new ArrayList();
-
- /**
- * Public setter for the {@link JobRegistry}.
- * @param registry the registry to set
- */
- public void setRegistry(JobRegistry registry) {
- this.registry = registry;
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader)
- */
- public void setResourceLoader(ResourceLoader resourceLoader) {
- this.resourceLoader = resourceLoader;
- }
-
- /**
- * Public getter for the errors.
- * @return the errors
- */
- public static List getErrors() {
- return errors;
- }
-
- private void register(String[] paths) throws DuplicateJobException {
- for (int i = 0; i < paths.length; i++) {
- String path = paths[i];
- ConfigurableListableBeanFactory beanFactory = new XmlBeanFactory(resourceLoader.getResource(path),
- parentContext.getAutowireCapableBeanFactory());
- String[] names = beanFactory.getBeanNamesForType(Job.class);
- for (int j = 0; j < names.length; j++) {
- registry.register(new ClassPathXmlApplicationContextJobFactory(names[j], path, parentContext));
- }
- }
- }
-
- public static void main(String[] args) throws Exception {
-
- final TaskExecutorLauncher launcher = new TaskExecutorLauncher();
- errors.clear();
-
- new Thread(new Runnable() {
- public void run() {
- try {
- launcher.run();
- }
- catch (RuntimeException e) {
- errors.add(e);
- throw e;
- }
- };
- }).start();
-
- while (launcher.parentContext == null) {
- Thread.sleep(100L);
- }
-
- // Paths to individual job configurations.
- final String[] paths = new String[] { "jobs/adhocLoopJob.xml", "jobs/footballJob.xml" };
-
- launcher.register(paths);
-
- System.out
- .println("Started application. "
- + "Please connect using JMX (remember to use -Dcom.sun.management.jmxremote if you can't see anything in Jconsole).");
- System.in.read();
-
- }
-
- private void run() {
-
- /*
- * A simple execution environment with an MBean for the JobLauncher,
- * which has an asynchronous TaskExecutor. This will be used as the
- * parent context for loading job configurations.
- */
- final ApplicationContext parent = new ClassPathXmlApplicationContext("adhoc-job-launcher-context.xml");
- parent.getAutowireCapableBeanFactory().autowireBeanProperties(this,
- AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
- parent.getAutowireCapableBeanFactory().initializeBean(this, "taskExecutorLauncher");
- this.parentContext = parent;
-
- }
-
-}
diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/quartz/QuartzBatchLauncher.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/quartz/QuartzBatchLauncher.java
deleted file mode 100644
index 439f574b1..000000000
--- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/quartz/QuartzBatchLauncher.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.batch.sample.quartz;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.batch.core.Job;
-import org.springframework.batch.core.configuration.JobRegistry;
-import org.springframework.batch.core.configuration.support.ClassPathXmlApplicationContextJobFactory;
-import org.springframework.batch.core.repository.DuplicateJobException;
-import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.xml.XmlBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-import org.springframework.core.io.ResourceLoader;
-
-public class QuartzBatchLauncher {
-
- private static Log log = LogFactory.getLog(QuartzBatchLauncher.class);
-
- private JobRegistry registry;
-
- private ResourceLoader resourceLoader;
-
- private ApplicationContext parentContext = null;
-
- /**
- * Public setter for the {@link JobRegistry}.
- * @param registry the registry to set
- */
- public void setRegistry(JobRegistry registry) {
- this.registry = registry;
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader)
- */
- public void setResourceLoader(ResourceLoader resourceLoader) {
- this.resourceLoader = resourceLoader;
- }
-
- private void register(String[] paths) throws DuplicateJobException {
- for (int i = 0; i < paths.length; i++) {
- String path = paths[i];
- ConfigurableListableBeanFactory beanFactory = new XmlBeanFactory(resourceLoader.getResource(path),
- parentContext.getAutowireCapableBeanFactory());
- String[] names = beanFactory.getBeanNamesForType(Job.class);
- for (int j = 0; j < names.length; j++) {
- registry.register(new ClassPathXmlApplicationContextJobFactory(names[j], path, parentContext));
- }
- }
- }
-
- public static void main(String[] args) throws Exception {
-
- final QuartzBatchLauncher launcher = new QuartzBatchLauncher();
-
- new Thread(new Runnable() {
- public void run() {
- launcher.run();
- };
- }).start();
-
- while (launcher.parentContext == null) {
- Thread.sleep(100L);
- }
-
- // Paths to individual job configurations.
- final String[] paths = new String[] { "jobs/adhocLoopJob.xml", "jobs/footballJob.xml" };
-
- launcher.register(paths);
-
- log.info("Started Quartz scheduler.");
- System.in.read();
- }
-
- private void run() {
-
- /*
- * A simple execution environment with a Quartz scheduler. This will be
- * used as the parent context for loading job configurations.
- */
- final ApplicationContext parent = new ClassPathXmlApplicationContext("quartz-job-launcher-context.xml");
- parent.getAutowireCapableBeanFactory().autowireBeanProperties(this,
- AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
- parent.getAutowireCapableBeanFactory().initializeBean(this, "quartzLauncher");
- this.parentContext = parent;
-
- }
-}
diff --git a/spring-batch-samples/src/main/resources/log4j.properties b/spring-batch-samples/src/main/resources/log4j.properties
index 79d0cd588..fcc475b7a 100644
--- a/spring-batch-samples/src/main/resources/log4j.properties
+++ b/spring-batch-samples/src/main/resources/log4j.properties
@@ -22,7 +22,7 @@ log4j.rootLogger=info, stdout
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
### enable spring
-log4j.logger.org.springframework=error
+log4j.logger.org.springframework=info
#log4j.logger.org.springframework.transaction=debug
#log4j.logger.org.springframework.jdbc.core=debug
#log4j.logger.org.springframework.orm=debug
diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/launch/RemoteLauncherTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/launch/RemoteLauncherTests.java
index 32a3cc592..ef20cbcf8 100644
--- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/launch/RemoteLauncherTests.java
+++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/launch/RemoteLauncherTests.java
@@ -15,17 +15,22 @@
*/
package org.springframework.batch.sample.launch;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import java.util.ArrayList;
import java.util.List;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
-import junit.framework.TestCase;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.junit.Before;
+import org.junit.Test;
import org.springframework.batch.core.launch.support.ExportedJobLauncher;
+import org.springframework.batch.core.launch.support.JobRegistryBackgroundJobRunner;
import org.springframework.jmx.MBeanServerNotFoundException;
import org.springframework.jmx.access.InvalidInvocationException;
import org.springframework.jmx.access.MBeanProxyFactoryBean;
@@ -35,7 +40,7 @@ import org.springframework.jmx.support.MBeanServerConnectionFactoryBean;
* @author Dave Syer
*
*/
-public class RemoteLauncherTests extends TestCase {
+public class RemoteLauncherTests {
private static Log logger = LogFactory.getLog(RemoteLauncherTests.class);
@@ -47,11 +52,14 @@ public class RemoteLauncherTests extends TestCase {
private static JobLoader loader;
+ @Test
public void testConnect() throws Exception {
- assertEquals(0, errors.size());
+ String message = errors.isEmpty() ? "" : errors.get(0).getMessage();
+ assertEquals(message, 0, errors.size());
assertTrue(isConnected());
}
+ @Test
public void testLaunchBadJob() throws Exception {
assertEquals(0, errors.size());
assertTrue(isConnected());
@@ -59,6 +67,7 @@ public class RemoteLauncherTests extends TestCase {
assertTrue("Should contain 'NoSuchJobException': " + result, result.indexOf("NoSuchJobException") >= 0);
}
+ @Test
public void testLaunchAndStopRealJob() throws Exception {
assertEquals(0, errors.size());
assertTrue(isConnected());
@@ -74,7 +83,8 @@ public class RemoteLauncherTests extends TestCase {
* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
- protected void setUp() throws Exception {
+ @Before
+ public void setUp() throws Exception {
if (launcher != null) {
return;
}
@@ -82,7 +92,7 @@ public class RemoteLauncherTests extends TestCase {
thread = new Thread(new Runnable() {
public void run() {
try {
- TaskExecutorLauncher.main(new String[0]);
+ JobRegistryBackgroundJobRunner.main("adhoc-job-launcher-context.xml", "jobs/adhocLoopJob.xml");
}
catch (Exception e) {
errors.add(e);
@@ -102,8 +112,8 @@ public class RemoteLauncherTests extends TestCase {
*/
private static boolean isConnected() throws Exception {
boolean connected = false;
- if (!TaskExecutorLauncher.getErrors().isEmpty()) {
- throw (RuntimeException) TaskExecutorLauncher.getErrors().get(0);
+ if (!JobRegistryBackgroundJobRunner.getErrors().isEmpty()) {
+ throw (RuntimeException) JobRegistryBackgroundJobRunner.getErrors().get(0);
}
if (launcher == null) {
MBeanServerConnectionFactoryBean connectionFactory = new MBeanServerConnectionFactoryBean();