diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/DefaultJobLoader.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/DefaultJobLoader.java similarity index 98% rename from spring-batch-samples/src/test/java/org/springframework/batch/sample/DefaultJobLoader.java rename to spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/DefaultJobLoader.java index 255fb7c08..eb9a3c3cd 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/DefaultJobLoader.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/DefaultJobLoader.java @@ -1,7 +1,7 @@ /** * */ -package org.springframework.batch.sample; +package org.springframework.batch.sample.launch; import java.util.HashMap; import java.util.Iterator; diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/ExportedJobLoader.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/ExportedJobLoader.java similarity index 94% rename from spring-batch-samples/src/test/java/org/springframework/batch/sample/ExportedJobLoader.java rename to spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/ExportedJobLoader.java index a0ce2d57f..fd9592ff5 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/ExportedJobLoader.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/ExportedJobLoader.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.batch.sample; +package org.springframework.batch.sample.launch; import java.util.Map; diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/JobLoader.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/JobLoader.java similarity index 94% rename from spring-batch-samples/src/test/java/org/springframework/batch/sample/JobLoader.java rename to spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/JobLoader.java index 4321530bc..d28b4bbc2 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/JobLoader.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/launch/JobLoader.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.batch.sample; +package org.springframework.batch.sample.launch; import java.util.Map; 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 index 8f07f730b..5debb8525 100644 --- 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 @@ -15,6 +15,9 @@ */ 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.repository.DuplicateJobException; @@ -39,6 +42,8 @@ public class TaskExecutorLauncher implements ResourceLoaderAware { private ApplicationContext parentContext = null; + private static List errors = new ArrayList(); + /** * Public setter for the {@link JobRegistry}. * @param registry the registry to set @@ -54,6 +59,14 @@ public class TaskExecutorLauncher implements ResourceLoaderAware { 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++) { @@ -70,10 +83,17 @@ public class TaskExecutorLauncher implements ResourceLoaderAware { public static void main(String[] args) throws Exception { final TaskExecutorLauncher launcher = new TaskExecutorLauncher(); + errors.clear(); new Thread(new Runnable() { public void run() { - launcher.run(); + try { + launcher.run(); + } + catch (RuntimeException e) { + errors.add(e); + throw e; + } }; }).start(); diff --git a/spring-batch-samples/src/main/resources/adhoc-job-launcher-context.xml b/spring-batch-samples/src/main/resources/adhoc-job-launcher-context.xml index 1e5c0fe7a..4282d83ec 100644 --- a/spring-batch-samples/src/main/resources/adhoc-job-launcher-context.xml +++ b/spring-batch-samples/src/main/resources/adhoc-job-launcher-context.xml @@ -37,7 +37,7 @@ key="spring:service=batch,bean=jobLauncher" value="org.springframework.batch.core.launch.support.ExportedJobLauncher" /> + value="org.springframework.batch.sample.launch.JobLoader" /> @@ -57,7 +57,7 @@ + class="org.springframework.batch.sample.launch.DefaultJobLoader"> 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 new file mode 100644 index 000000000..00fafb83b --- /dev/null +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/launch/RemoteLauncherTests.java @@ -0,0 +1,110 @@ +/* + * 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 junit.framework.TestCase; + +import org.springframework.batch.core.launch.support.ExportedJobLauncher; +import org.springframework.jmx.access.InvalidInvocationException; +import org.springframework.jmx.access.MBeanProxyFactoryBean; + +/** + * @author Dave Syer + * + */ +public class RemoteLauncherTests extends TestCase { + + private static List errors = new ArrayList(); + private static Thread thread; + private static ExportedJobLauncher launcher; + + public void testConnect() throws Exception { + doLaunch(); + assertEquals(0, errors.size()); + assertTrue(isConnected()); + } + + public void testLaunchBadJob() throws Exception { + doLaunch(); + assertEquals(0, errors.size()); + assertTrue(isConnected()); + String result = launcher.run("foo"); + assertTrue("Should contain 'NoSuchJobException': "+result, result.indexOf("NoSuchJobException")>=0); + } + + public void testLaunchAndStopRealJob() throws Exception { + doLaunch(); + assertEquals(0, errors.size()); + assertTrue(isConnected()); + String result = launcher.run("loopJob"); + assertTrue("Should contain 'JobExecution': "+result, result.indexOf("JobExecution: id=")>=0); + Thread.sleep(500); + assertTrue(launcher.isRunning()); + launcher.stop(); + assertFalse(launcher.isRunning()); + } + + /** + * @throws Exception + */ + private static void doLaunch() throws Exception { + if (launcher!=null) { + return; + } + System.setProperty("com.sun.management.jmxremote", ""); + thread = new Thread(new Runnable() { + public void run() { + try { + TaskExecutorLauncher.main(new String[0]); + } + catch (Exception e) { + errors.add(e); + } + } + }); + thread.start(); + MBeanProxyFactoryBean factory = new MBeanProxyFactoryBean(); + factory.setObjectName("spring:service=batch,bean=jobLauncher"); + factory.setProxyInterface(ExportedJobLauncher.class); + factory.afterPropertiesSet(); + launcher = (ExportedJobLauncher) factory.getObject(); + int count = 0; + while (!isConnected() && count ++<10) { + Thread.sleep(1000); + } + } + + /** + * + */ + private static boolean isConnected() { + boolean connected = false; + if (!TaskExecutorLauncher.getErrors().isEmpty()) { + throw (RuntimeException) TaskExecutorLauncher.getErrors().get(0); + } + try { + launcher.isRunning(); + connected = true; + } catch (InvalidInvocationException e) { + // ignore + } + return connected; + } + +}