├── .gitignore ├── LICENSE ├── README.md ├── hello-world-groovy ├── LICENSE ├── pom.xml └── src │ ├── main │ ├── groovy │ │ └── de │ │ │ └── langmi │ │ │ └── spring │ │ │ └── batch │ │ │ └── tutorials │ │ │ └── helloworld │ │ │ └── HelloWorldTasklet.groovy │ └── resources │ │ ├── commons-logging.properties │ │ ├── simplelog.properties │ │ └── spring │ │ └── batch │ │ └── job │ │ └── hello-world-job.xml │ └── test │ └── groovy │ └── de │ └── langmi │ └── spring │ └── batch │ └── tutorials │ └── helloworld │ └── HelloWorldJobConfigurationTest.groovy ├── hello-world-java ├── LICENSE ├── README.md ├── build.gradle ├── buildfile ├── pom.xml ├── spring-batch-concept-chunk.png ├── spring-batch-concept-job.png ├── spring-batch-concept-step.png ├── spring-batch-tutorial-hello-world-logo.png └── src │ ├── main │ ├── java │ │ └── de │ │ │ └── langmi │ │ │ └── spring │ │ │ └── batch │ │ │ └── tutorials │ │ │ └── helloworld │ │ │ └── HelloWorldTasklet.java │ └── resources │ │ ├── commons-logging.properties │ │ ├── simplelog.properties │ │ └── spring │ │ └── batch │ │ └── job │ │ └── hello-world-job.xml │ └── test │ └── java │ └── de │ └── langmi │ └── spring │ └── batch │ └── tutorials │ └── helloworld │ ├── HelloWorldJobConfigurationManualTest.java │ ├── HelloWorldJobConfigurationTest.java │ └── HelloWorldTaskletTest.java ├── pom.xml └── spring-batch-tutorials-logo.png /.gitignore: -------------------------------------------------------------------------------- 1 | /hello-world-java/catalog.xml 2 | /hello-world-java/target 3 | /hello-world-groovy/catalog.xml 4 | /hello-world-groovy/target 5 | /hello-world-groovy/.idea 6 | /hello-world-groovy/*.iml 7 | /hello-world-java/reports 8 | /hello-world-java/build 9 | /hello-world-java/.gradle/ 10 | /hello-world-java/gradle-app.setting -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2011 Michael R. Lange . 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Batch Tutorials 2 | 3 | 4 | ![Spring Batch Tutorials Logo][spring-batch-tutorial-logo] 5 | 6 | Spring Batch tutorials, covering all the aspects and methods of this wonderful Java framework. 7 | 8 | ## Introduction 9 | 10 | Hello and welcome to Spring Batch tutorials for new and advanced users alike. 11 | 12 | The tutorials will provide you with step-by-step guides for using Spring Batch and some background informations for the concepts. If you are ready to get more, head over to my [Spring Batch Examples][spring-batch-examples], [Templates][spring-batch-templates] and [Maven Archetypes][spring-batch-archetypes] here at github too. 13 | 14 | If you want to see a new tutorial or spot an error, do not hesitate to [raise an issue][issue]. For questions to the Spring Batch framework itself, i suggest to ask at [Stackoverflow][stackoverflow] or the official [Spring Batch Forum][spring-batch-forum] (i'm active at both). 15 | 16 | ## Tutorial Topics 17 | 18 | * The inevitable [Hello World!][hello-world-java] 19 | * A more exotic [Hello World!][hello-world-groovy] with [Groovy][groovy] 20 | 21 | ## General Informations 22 | 23 | All Spring Batch Tutorials: 24 | 25 | * are individual maven projects, the pom.xml in the root directory is only for a convenient _build all_ feature 26 | * are tested with: 27 | * Spring Batch 2.1.8.RELEASE 28 | * Spring Framework 3.1.0.RELEASE 29 | * are provided "as is", no guarantees 30 | * the font used in logo is [Yanone Kaffeesatz][yanone-kaffeesatz] 31 | 32 | ## About Me 33 | 34 | I am [Michael R. Lange][homepage] from Germany and would describe myself as a [Code Craftsman][code-craftsman]. 35 | 36 | My motivation to write the tutorials comes from the usage at work and at home too, so it was about time to write and share some of the knowledge i picked up around. 37 | 38 | ## License 39 | 40 | Apache 2.0 License 41 | 42 | [code-craftsman]: http://www.joelonsoftware.com/articles/Craftsmanship.html 43 | [groovy]: http://groovy.codehaus.org/ 44 | [hello-world-java]: https://github.com/langmi/spring-batch-tutorials/tree/master/hello-world-java 45 | [hello-world-groovy]: https://github.com/langmi/spring-batch-tutorials/tree/master/hello-world-groovy 46 | [homepage]: http://langmi.de 47 | [issue]: https://github.com/langmi/spring-batch-tutorials/issues 48 | [spring-batch-archetypes]: https://github.com/langmi/spring-batch-archetypes 49 | [spring-batch-examples]: https://github.com/langmi/spring-batch-examples 50 | [spring-batch-forum]: http://forum.springsource.org/forumdisplay.php?41-Batch 51 | [spring-batch-templates]: https://github.com/langmi/spring-batch-templates 52 | [spring-batch-tutorial-logo]: https://github.com/langmi/spring-batch-tutorials/raw/master/spring-batch-tutorials-logo.png 53 | [stackoverflow]: http://stackoverflow.com/questions/tagged/spring-batch 54 | [yanone-kaffeesatz]: http://www.yanone.de/typedesign/kaffeesatz/ -------------------------------------------------------------------------------- /hello-world-groovy/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2011 Michael R. Lange . 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /hello-world-groovy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 4.0.0 19 | 20 | de.langmi.spring.batch.tutorials 21 | hello-world-groovy 22 | 1.0-SNAPSHOT 23 | jar 24 | 25 | hello-world-groovy 26 | https://github.com/langmi/spring-batch-tutorials 27 | 28 | 29 | Spring Batch Hello World! with groovy Tutorial 30 | This projects needs: 31 | 32 | * Java 1.6+ 33 | * Maven 3+ 34 | 35 | see maven-enforcer-plugin configuration. 36 | 37 | 38 | 39 | 40 | Apache 2 41 | http://www.apache.org/licenses/LICENSE-2.0.txt 42 | manual 43 | 44 | Declared 'manual' distribution, because there are no plans 45 | to upload the project to a maven repository. 46 | 47 | 48 | 49 | 50 | 51 | 52 | michael 53 | Michael Lange 54 | michael.r.lange@langmi.de 55 | http://www.langmi.de 56 | 57 | architect 58 | developer 59 | 60 | +1 61 | 62 | 63 | 64 | 65 | 66 | UTF-8 67 | 1.6 68 | 2.0.0-beta-2 69 | 70 | 2.1.8.RELEASE 71 | 3.1.0.RELEASE 72 | 73 | 74 | 75 | 76 | 78 | 126 | 127 | org.codehaus.gmaven 128 | gmaven-plugin 129 | 1.3 130 | 131 | 132 | 133 | generateStubs 134 | compile 135 | generateTestStubs 136 | testCompile 137 | 138 | 139 | 1.7 140 | 141 | 142 | 143 | 144 | 145 | org.codehaus.gmaven.runtime 146 | gmaven-runtime-1.7 147 | 1.2 148 | 149 | 150 | org.codehaus.groovy 151 | groovy-all 152 | 153 | 154 | 155 | 156 | org.codehaus.groovy 157 | groovy-all 158 | ${groovy.version} 159 | 160 | 161 | 162 | 163 | 170 | maven-resources-plugin 171 | 2.5 172 | 173 | ${project.build.sourceEncoding} 174 | 175 | 176 | 177 | 180 | copy-resources 181 | validate 182 | 183 | copy-resources 184 | 185 | 186 | ${basedir}/target/classes 187 | 188 | 189 | src/main/groovy 190 | true 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 207 | maven-shade-plugin 208 | 1.5 209 | 210 | 211 | package 212 | 213 | shade 214 | 215 | 216 | 217 | 218 | org.springframework.batch.core.launch.support.CommandLineJobRunner 219 | 220 | 221 | META-INF/spring.handlers 222 | 223 | 224 | META-INF/spring.schemas 225 | 226 | 227 | true 228 | 229 | executable 230 | 231 | 232 | 233 | 234 | 235 | 239 | maven-enforcer-plugin 240 | 1.0.1 241 | 242 | 243 | enforce-maven 244 | 245 | enforce 246 | 247 | 248 | 249 | 250 | ${project.java.version} 251 | 252 | 253 | 258 | 3.0.0 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | org.codehaus.groovy 271 | groovy-all 272 | ${groovy.version} 273 | 274 | 275 | 276 | org.springframework 277 | spring-beans 278 | ${spring.framework.version} 279 | 280 | 281 | org.springframework 282 | spring-context 283 | ${spring.framework.version} 284 | 285 | 286 | org.springframework 287 | spring-jdbc 288 | ${spring.framework.version} 289 | 290 | 291 | 292 | org.springframework.batch 293 | spring-batch-core 294 | ${spring.batch.version} 295 | 296 | 297 | org.springframework.batch 298 | spring-batch-infrastructure 299 | ${spring.batch.version} 300 | 301 | 302 | 303 | org.springframework.batch 304 | spring-batch-test 305 | ${spring.batch.version} 306 | test 307 | 308 | 309 | org.springframework 310 | spring-test 311 | ${spring.framework.version} 312 | test 313 | 314 | 315 | 316 | -------------------------------------------------------------------------------- /hello-world-groovy/src/main/groovy/de/langmi/spring/batch/tutorials/helloworld/HelloWorldTasklet.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2011 Michael R. Lange . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.langmi.spring.batch.tutorials.helloworld 17 | 18 | import org.springframework.batch.core.StepContribution; 19 | import org.springframework.batch.core.scope.context.ChunkContext; 20 | import org.springframework.batch.core.step.tasklet.Tasklet; 21 | import org.springframework.batch.repeat.RepeatStatus; 22 | 23 | /** 24 | * Tasklet(step) which prints out a friendly "Hello World!". 25 | * 26 | * @author Michael R. Lange 27 | */ 28 | class HelloWorldTasklet implements Tasklet{ 29 | 30 | def RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) { 31 | println("Groovy World!") 32 | return RepeatStatus.FINISHED 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /hello-world-groovy/src/main/resources/commons-logging.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Michael R. Lange . 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ######################################## 15 | # 16 | # logging configuration is only for a real simple spring batch 'hello world' example 17 | org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog -------------------------------------------------------------------------------- /hello-world-groovy/src/main/resources/simplelog.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Michael R. Lange . 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ######################################## 15 | # 16 | # logging configuration is only for a real simple spring batch 'hello world' example 17 | # loglevel = error to see the 'hello world' text only 18 | org.apache.commons.logging.simplelog.defaultlog=error 19 | -------------------------------------------------------------------------------- /hello-world-groovy/src/main/resources/spring/batch/job/hello-world-job.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 23 | 24 | 25 | Simple Spring Batch Configuration 26 | 27 | - one step 28 | - prints out "Hello World!" 29 | 30 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 44 | 47 | 48 | 51 | 52 | 54 | 55 | -------------------------------------------------------------------------------- /hello-world-groovy/src/test/groovy/de/langmi/spring/batch/tutorials/helloworld/HelloWorldJobConfigurationTest.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2011 Michael R. Lange . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.langmi.spring.batch.tutorials.helloworld 17 | 18 | import groovy.util.GroovyTestCase 19 | import org.springframework.context.ApplicationContext; 20 | import org.springframework.context.support.FileSystemXmlApplicationContext; 21 | import org.springframework.batch.core.BatchStatus; 22 | import org.springframework.batch.core.Job; 23 | import org.springframework.batch.core.JobExecution; 24 | import org.springframework.batch.core.JobParameters; 25 | import org.springframework.batch.core.launch.JobLauncher; 26 | 27 | 28 | 29 | class HelloWorldJobConfigurationTest extends GroovyTestCase { 30 | 31 | void testFoo(){ 32 | // load ApplicationContext 33 | ApplicationContext context = new FileSystemXmlApplicationContext("src/main/resources/spring/batch/job/hello-world-job.xml"); 34 | // get job 35 | Job job = context.getBean(Job.class); 36 | // get job launcher 37 | JobLauncher jobLauncher = context.getBean(JobLauncher.class); 38 | // start job 39 | JobExecution jobExecution = jobLauncher.run(job, new JobParameters()); 40 | 41 | // assertion 42 | assert BatchStatus.COMPLETED == jobExecution.getStatus(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /hello-world-java/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2011 Michael R. Lange . 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /hello-world-java/README.md: -------------------------------------------------------------------------------- 1 | # "Hello World!" with Spring Batch 2.1 2 | 3 | ![Logo][spring-batch-tutorial-hello-world-logo] 4 | 5 | ## Summary 6 | 7 | In this tutorial, we will create a really simple [Hello World!][hello-world] program with [Spring Batch][spring-batch] Version 2.1 and learn some basics for this amazing Java [batch processing][wikipedia-batch-processing] framework. 8 | 9 | You will need at least a basic understanding of the [Spring (Core) framework][spring-core] to get along with the tutorial. 10 | 11 | ## For the Impatient 12 | 13 | If you are in a hurry or just the code-first type, you can jump right to the source here on [my github repository][github-repo], dive into the hello-world-java directory. 14 | 15 | ## Introduction 16 | 17 | ### What is Spring Batch? 18 | 19 | From the [official Spring Batch website][spring-batch]: 20 | 21 | > Spring Batch is a lightweight, comprehensive batch framework designed to enable the development of robust batch applications vital for the daily operations of enterprise systems. 22 | 23 | Doesn't that sound like the usual sales pitch? Ok lets try it with (my) own words: 24 | 25 | > Spring Batch is a framework, which does the grunt work for your Java batch needs and provides lots of ready-to-use implementations to keep your own code minimal. 26 | 27 | 28 | ### Basic Spring Batch Concepts 29 | 30 | The official reference covers the [Spring Batch concepts][spring-batch-domain-concepts] in every detail, but for this tutorial we can start with a more simplified view: 31 | 32 | A Spring Batch program usually consists of a *Job*, which encapsulates a flow of *steps*, where a step can be seen as abstract isolated unit of work. Here that is visualized with a sequential flow example: 33 | 34 | ![Spring Batch Job][spring-batch-concept-job] 35 | 36 | A standard Step *reads* data, *processes* it and *writes* data, until the data from the reader is exhausted. 37 | 38 | ![Spring Batch Step][spring-batch-concept-step] 39 | 40 | The data is handled with a so called [Chunk Oriented Processing][chunk-oriented-processing] approach, where the data is read individually, processed individually, but written in *chunks*. 41 | 42 | ![Spring Batch Chunk][spring-batch-concept-chunk] 43 | 44 | The chunks play a role for the transactional behavior too, Spring Batch commits a transaction after each chunk. Thats enough for the basic concepts, time to get ready for some coding. 45 | 46 | ## Get Ready For Coding! 47 | 48 | The Spring Batch framework is really lightweight, but that comes at the prize of a little more complex XML configuration. It is a **Spring** framework after all. 49 | 50 | ### Spring Batch Configuration 51 | 52 | The configuration needed to get a Spring Batch program running roughly consists of two parts: 53 | 54 | * Spring Batch infrastructure 55 | * Spring Batch Job definition 56 | 57 | 58 | #### Spring Batch Infrastructure 59 | 60 | Under the hood Spring Batch works with some tables to keep the state of the jobs and steps and to provide re-startability. 61 | The tables are accessed with a DAO called [Job Repository][job-repository] and to start a Job the framework provides a [Job Launcher][job-launcher]. 62 | Because a job works with transactions, a *transaction manager* is mandatory. 63 | 64 | To keep this tutorial simple we use a table-less Job Repository and a dummy transaction manager, translated to the Spring and Spring Batch XML configuration it looks like this: 65 | 66 | 69 | 70 | 73 | 74 | 76 | 77 | This is at the same time the most minimal Spring Batch infrastructure configuration possible and does not need any self-made code, all implementations are provided by the framework. 78 | 79 | #### Spring Batch Job Definition 80 | 81 | The *Job* definition - for this tutorial - is quite short: 82 | 83 | 84 | 85 | 86 | 87 | 88 | 90 | 91 | In contrast to the introduction of the basic concepts, we use a so called [Tasklet Step][tasklet-step], without the standard Reader, Processor and Writer. A *Tasklet Step* bypasses the standard Step concept and makes it possible to implement just one method, like printing out *Hello World!*. 92 | 93 | #### Complete XML 94 | 95 | All XML taken from the configurations above and joined in one file: 96 | 97 | 98 | 106 | 107 | 108 | Simple Spring Batch Configuration 109 | 110 | - one tasklet step 111 | - prints out "Hello World!" 112 | - setup without database, uses in-memory JobRepository 113 | - not restartable 114 | 115 | 116 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 128 | 129 | 132 | 133 | 136 | 137 | 139 | 140 | 141 | 142 | ### Java Code 143 | 144 | In the Job configuration we configured a Tasklet Step, here is the missing source-code: 145 | 146 | package de.langmi.spring.batch.tutorials.helloworld; 147 | 148 | import org.springframework.batch.core.StepContribution; 149 | import org.springframework.batch.core.scope.context.ChunkContext; 150 | import org.springframework.batch.core.step.tasklet.Tasklet; 151 | import org.springframework.batch.repeat.RepeatStatus; 152 | 153 | public class HelloWorldTasklet implements Tasklet { 154 | 155 | /** {@inheritDoc} */ 156 | @Override 157 | public RepeatStatus execute(StepContribution contribution, 158 | ChunkContext chunkContext) throws Exception { 159 | 160 | // why not using println? because it makes testing harder, *nix and 161 | // windows think different about new line as in \n vs \r\n 162 | System.out.print("Hello World!"); 163 | 164 | return RepeatStatus.FINISHED; 165 | } 166 | } 167 | 168 | And that's it, yes really that and the configuration is a complete Spring Batch. 169 | 170 | ## Testing 171 | 172 | Before the batch escapes will be released it needs some tests. 173 | 174 | ### Testing The Tasklet Step 175 | 176 | The Tasklet implementation is pure Java, so we can test it as that with [JUnit][junit]: 177 | 178 | public class HelloWorldTaskletTest { 179 | 180 | private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); 181 | private final Tasklet tasklet = new HelloWorldTasklet(); 182 | 183 | @Test 184 | public void testExecute() throws Exception { 185 | tasklet.execute(null, null); 186 | assertEquals("Hello World!", outContent.toString()); 187 | } 188 | 189 | @Before 190 | public void setUpStreams() { 191 | // catch system out 192 | System.setOut(new PrintStream(outContent)); 193 | } 194 | 195 | @After 196 | public void cleanUpStreams() { 197 | // reset JVM standard 198 | System.setOut(null); 199 | } 200 | } 201 | 202 | ### Testing Complete Job 203 | 204 | To test the complete Job we can use a lot of the Spring JUnit [test utilities][spring-testing]. The only difference to a standard Spring test is the use of the Job Launcher, which is needed to launch a job. 205 | 206 | @ContextConfiguration(locations = {"classpath*:spring/batch/job/hello-world-job.xml"}) 207 | @RunWith(SpringJUnit4ClassRunner.class) 208 | public class HelloWorldJobConfigurationTest { 209 | 210 | @Autowired 211 | private Job job; 212 | @Autowired 213 | private JobLauncher jobLauncher; 214 | private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); 215 | 216 | /** Simple Launch Test. */ 217 | @Test 218 | public void launchJob() throws Exception { 219 | // launch the job 220 | JobExecution jobExecution = jobLauncher.run(job, new JobParameters()); 221 | 222 | // assert job run status 223 | assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); 224 | 225 | // assert sysoutput 226 | assertEquals("Hello World!", outContent.toString()); 227 | } 228 | 229 | @Before 230 | public void setUpStreams() { 231 | // catch system out 232 | System.setOut(new PrintStream(outContent)); 233 | } 234 | 235 | @After 236 | public void cleanUpStreams() { 237 | // reset JVM standard 238 | System.setOut(null); 239 | } 240 | } 241 | 242 | This test is essentially an integration test. 243 | 244 | ## Run The Spring Batch Job 245 | 246 | To run a Spring Batch Job one can use [Spring Batch Admin][spring-batch-admin], which is really out of scope for this tutorial, so we will use the standard Java [Main-Class][main-class] concept with an executable [JAR][jar]. 247 | 248 | ### Which Main Class ? 249 | 250 | The nice thing about Spring frameworks is, right when you need a ready-to-use implementation, the framework has it. We need a Main Class, which can be configured easily and starts the job, here it is: [CommandLineJobRunner][CommandLineJobRunner]. 251 | 252 | The only thing left is an executable JAR, to create one the pom.xml from the tutorial sources has a configuration for the [Maven-shade Plugin][maven-shade-plugin]. To use it just run the usual: `mvn clean install` and there will be an `hello-world-java-1.0-executable.jar` ready for use. 253 | 254 | ### Run It! 255 | 256 | It's about time to end this tutorial, so here is the code to run the job: 257 | 258 | `java -jar hello-world-java-1.0-executable.jar spring/batch/job/hello-world-job.xml helloWorldJob` 259 | 260 | If all worked well, you see now a friendly `Hello World!`. 261 | 262 | ## Conclusion 263 | 264 | By following this tutorial you learned some Spring Batch basic concepts and built a simple *Hello World!* program. The next tutorials will cover more advanced concepts like *Read, Process, Write* or *Logging*. 265 | 266 | ### Did you know? 267 | 268 | Spring Batch was first [introduced][first-introduction] in 2007. Back then the framework was created by Interface21 - now known as [Springsource][springsource] - and [Accenture][accenture]. It has seen only 2 major versions so far, but the [transition from version 1 to 2][changes-1-to-2] included a massive refactoring of the core concepts. In fact the chunk oriented processing concept was first introduced with Spring Batch version 2. 269 | 270 | ## Meta 271 | 272 | * tested with: 273 | * Java 1.6 274 | * Maven 3 275 | * [Spring Batch][spring-batch] 2.1.8.RELEASE 276 | * [Spring Framework(core)][spring-core] 3.1.0.RELEASE 277 | * used IDE: primarily programmed with [Netbeans][netbeans] 7.0 278 | * license: [Apache 2.0 License][apache-license] 279 | 280 | ### Maven, Buildr, Gradle and Friends 281 | 282 | I provided some build manager configurations for: 283 | 284 | * [Buildr][buildr] - see [buildfile][buildfile], tested with Buildr 1.4.6 285 | * [Gradle][gradle] - see [build.gradle][build-gradle], tested with Gradle 1.0-milestone-5 286 | * [Maven][maven] - see [pom.xml][pom-xml], needs Maven 3+ 287 | 288 | Each configuration file contains informations on used versions and general setup. 289 | 290 | If you work without a build manager you can download all needed libraries from [Spring Batch downloads][spring-batch-downloads], but remember this tutorial is tested with Spring Batch Version 2.1 only. 291 | 292 | 293 | [accenture]: http://www.accenture.com/ "Accenture official home page" 294 | [apache-license]: http://www.apache.org/licenses/LICENSE-2.0.txt "Apache 2.0 License" 295 | [buildr]: http://buildr.apache.org/ "Buildr official home page" 296 | [buildfile]: https://github.com/langmi/spring-batch-tutorials/blob/master/hello-world-java/buildfile 297 | [build-gradle]: https://github.com/langmi/spring-batch-tutorials/blob/master/hello-world-java/build.gradle 298 | [changes-1-to-2]: http://static.springsource.org/spring-batch/trunk/migration/2.0-highlights.html "Changes from Spring Batch 1.x to 2.0" 299 | [chunk-oriented-processing-news]: http://static.springsource.org/spring-batch/reference/html/whatsNew.html#whatsNewChunkOrientedProcessing 300 | [chunk-oriented-processing]: http://static.springsource.org/spring-batch/reference/html/configureStep.html#chunkOrientedProcessing 301 | [CommandLineJobRunner]: http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/core/launch/support/CommandLineJobRunner.html 302 | [first-introduction]: http://forum.springsource.org/showthread.php?38417-Spring-Batch-Announcement "first Spring Batch announcement from 2007" 303 | [gradle]: http://www.gradle.org/ "Gradle official home page" 304 | [github-repo]: https://github.com/langmi/spring-batch-tutorials "My Github Repository for Spring Batch Tutorials Sources" 305 | [jar]: http://en.wikipedia.org/wiki/JAR_(file_format) 306 | [job-launcher]: http://static.springsource.org/spring-batch/reference/html/domain.html#domainJobLauncher 307 | [job-repository]: http://static.springsource.org/spring-batch/reference/html/domain.html#domainJobRepository 308 | [junit]: http://www.junit.org/ 309 | [hello-world]: http://en.wikipedia.org/wiki/Hello_world_program "Wikipedia: Hello World Programm" 310 | [main-class]:http://docs.oracle.com/javase/tutorial/deployment/jar/appman.html 311 | [maven]: http://maven.apache.org/index.html "Maven official home page" 312 | [maven-shade-plugin]: http://maven.apache.org/plugins/maven-shade-plugin/ 313 | [pom-xml]: http://maven.apache.org/guides/introduction/introduction-to-the-pom.html 314 | [springsource]: http://www.springsource.com/ "Springsource official home page" 315 | [spring-batch]: http://static.springsource.org/spring-batch/ "Spring Batch official home page" 316 | [spring-batch-concept-chunk]: https://github.com/langmi/spring-batch-tutorials/raw/master/hello-world-java/spring-batch-concept-chunk.png 317 | [spring-batch-concept-job]: https://github.com/langmi/spring-batch-tutorials/raw/master/hello-world-java/spring-batch-concept-job.png 318 | [spring-batch-concept-step]: https://github.com/langmi/spring-batch-tutorials/raw/master/hello-world-java/spring-batch-concept-step.png 319 | [spring-core]: http://www.springsource.org/spring-core/ "Spring Core Framework official home page" 320 | [spring-batch-admin]: http://static.springsource.org/spring-batch-admin/getting-started.html 321 | [spring-batch-domain-concepts]: http://static.springsource.org/spring-batch/reference/html/domain.html 322 | [spring-batch-downloads]: http://static.springsource.org/spring-batch/downloads.html 323 | [spring-batch-tutorial-hello-world-logo]: https://github.com/langmi/spring-batch-tutorials/raw/master/hello-world-java/spring-batch-tutorial-hello-world-logo.png 324 | [spring-testing]: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/testing.html 325 | [tasklet-step]: http://static.springsource.org/spring-batch/reference/html/configureStep.html#taskletStep 326 | [wikipedia-batch-processing]: http://en.wikipedia.org/wiki/Batch_processing 327 | -------------------------------------------------------------------------------- /hello-world-java/build.gradle: -------------------------------------------------------------------------------- 1 | /* Gradle buildfile 2 | 3 | tested with: 4 | * Gradle 1.0-milestone-5 5 | * Groovy 1.7.10 6 | * Java 1.6.0_29 7 | 8 | see http://www.gradle.org/ for more informations to Gradle */ 9 | 10 | apply plugin: 'java' 11 | apply plugin: 'maven' 12 | 13 | repositories { 14 | mavenLocal() 15 | mavenCentral() 16 | } 17 | 18 | project.group = "de.langmi.spring.batch.tutorials" 19 | project.version = "1.0-SNAPSHOT" 20 | 21 | sourceCompatibility = '1.6' 22 | targetCompatibility = '1.6' 23 | 24 | // to prevent problems with transitive dependencies i provided the complete needed list 25 | dependencies { 26 | compile "aopalliance:aopalliance:1.0" 27 | compile "com.thoughtworks.xstream:xstream:1.3" 28 | compile "commons-logging:commons-logging:1.1.1" 29 | compile "org.codehaus.jettison:jettison:1.1" 30 | compile "org.springframework:spring-aop:3.0.6.RELEASE" 31 | compile "org.springframework:spring-asm:3.0.6.RELEASE" 32 | compile "org.springframework:spring-beans:3.0.6.RELEASE" 33 | compile "org.springframework:spring-context:3.0.6.RELEASE" 34 | compile "org.springframework:spring-core:3.0.6.RELEASE" 35 | compile "org.springframework:spring-expression:3.0.6.RELEASE" 36 | compile "org.springframework:spring-jdbc:3.0.6.RELEASE" 37 | compile "org.springframework:spring-tx:3.0.6.RELEASE" 38 | compile "org.springframework.batch:spring-batch-core:2.1.8.RELEASE" 39 | compile "org.springframework.batch:spring-batch-infrastructure:2.1.8.RELEASE" 40 | 41 | testCompile "commons-collections:commons-collections:3.2" 42 | testCompile "commons-dbcp:commons-dbcp:1.2.2" 43 | testCompile "commons-io:commons-io:1.4" 44 | testCompile "commons-pool:commons-pool:1.3" 45 | testCompile "junit:junit:4.10" 46 | testCompile "org.hamcrest:hamcrest-core:1.1" 47 | testCompile "org.springframework.batch:spring-batch-test:2.1.8.RELEASE" 48 | testCompile "org.springframework:spring-test:3.0.6.RELEASE" 49 | } -------------------------------------------------------------------------------- /hello-world-java/buildfile: -------------------------------------------------------------------------------- 1 | =begin 2 | Buildr buildfile 3 | 4 | tested with: 5 | * Buildr 1.4.6 6 | * Ruby 1.8.7 7 | * Gem 1.8.8 8 | * Java 1.6.0_29 9 | 10 | see http://buildr.apache.org/index.html for more informations to buildr 11 | =end 12 | 13 | repositories.remote << 'http://repo1.maven.org/maven2/' 14 | 15 | # to prevent problems with transitive dependencies i provided the complete needed list 16 | COMPILE_ARTIFACTS = [ 17 | 'aopalliance:aopalliance:jar:1.0', 18 | 'com.thoughtworks.xstream:xstream:jar:1.3', 19 | 'commons-logging:commons-logging:jar:1.1.1', 20 | 'org.codehaus.jettison:jettison:jar:1.1', 21 | 'org.springframework:spring-aop:jar:3.0.6.RELEASE', 22 | 'org.springframework:spring-asm:jar:3.0.6.RELEASE', 23 | 'org.springframework:spring-beans:jar:3.0.6.RELEASE', 24 | 'org.springframework:spring-context:jar:3.0.6.RELEASE', 25 | 'org.springframework:spring-core:jar:3.0.6.RELEASE', 26 | 'org.springframework:spring-expression:jar:3.0.6.RELEASE', 27 | 'org.springframework:spring-jdbc:jar:3.0.6.RELEASE', 28 | 'org.springframework:spring-tx:jar:3.0.6.RELEASE', 29 | 'org.springframework.batch:spring-batch-core:jar:2.1.8.RELEASE', 30 | 'org.springframework.batch:spring-batch-infrastructure:jar:2.1.8.RELEASE' 31 | ] 32 | # to prevent problems with transitive dependencies i provided the complete needed list 33 | TEST_ARTIFACTS = [ 34 | 'commons-collections:commons-collections:jar:3.2', 35 | 'commons-dbcp:commons-dbcp:jar:1.2.2', 36 | 'commons-io:commons-io:jar:1.4', 37 | 'commons-pool:commons-pool:jar:1.3', 38 | 'org.hamcrest:hamcrest-core:jar:1.1', 39 | 'commons-pool:commons-pool:jar:1.3', 40 | 'org.hamcrest:hamcrest-core:jar:1.1', 41 | # junit is optional, buildr 1.4.6 uses junit 4.8.2 as default 42 | 'junit:junit:jar:4.10', 43 | 'org.springframework.batch:spring-batch-test:jar:2.1.8.RELEASE', 44 | 'org.springframework:spring-test:jar:3.0.6.RELEASE' 45 | ] 46 | 47 | desc 'hello-world-java' 48 | define 'hello-world-java' do 49 | project.group = 'de.langmi.spring.batch.tutorials' 50 | project.version = '1.0-SNAPSHOT' 51 | compile.options.target = '1.6' 52 | compile.with COMPILE_ARTIFACTS 53 | test.with TEST_ARTIFACTS 54 | package :jar, :id => 'hello-world-java' 55 | end 56 | -------------------------------------------------------------------------------- /hello-world-java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 19 | 20 | 4.0.0 21 | 22 | de.langmi.spring.batch.tutorials 23 | hello-world-java 24 | 1.0 25 | jar 26 | 27 | hello-world-java 28 | https://github.com/langmi/spring-batch-tutorials 29 | 30 | 31 | A simple Spring Batch "Hello World!" tutorial. 32 | This projects needs: 33 | 34 | * Java 1.6+ 35 | * Maven 3+ 36 | 37 | see maven-enforcer-plugin configuration. 38 | 39 | 40 | 41 | 42 | Apache 2 43 | http://www.apache.org/licenses/LICENSE-2.0.txt 44 | manual 45 | 46 | Declared 'manual' distribution, because there are no plans 47 | to upload the project to a maven repository. 48 | 49 | 50 | 51 | 52 | 53 | 54 | michael 55 | Michael Lange 56 | michael.r.lange@langmi.de 57 | http://www.langmi.de 58 | 59 | architect 60 | developer 61 | 62 | +1 63 | 64 | 65 | 66 | 67 | 68 | UTF-8 69 | 1.6 70 | 71 | true 72 | false 73 | 74 | 2.1.8.RELEASE 75 | 3.1.0.RELEASE 76 | 77 | 78 | 79 | 80 | 81 | 89 | maven-compiler-plugin 90 | 2.3.2 91 | 92 | ${project.java.version} 93 | ${project.java.version} 94 | ${project.build.sourceEncoding} 95 | ${maven.compiler.debug} 96 | ${maven.compiler.optimize} 97 | true 98 | 99 | 100 | 101 | 104 | maven-resources-plugin 105 | 2.5 106 | 107 | ${project.build.sourceEncoding} 108 | 109 | 110 | 111 | 118 | maven-surefire-plugin 119 | 2.9 120 | 121 | ${maven.surefire.forkmode} 122 | 123 | 124 | 125 | 135 | maven-shade-plugin 136 | 1.5 137 | 138 | 139 | package 140 | 141 | shade 142 | 143 | 144 | 145 | 146 | org.springframework.batch.core.launch.support.CommandLineJobRunner 147 | 148 | 149 | META-INF/spring.handlers 150 | 151 | 152 | META-INF/spring.schemas 153 | 154 | 155 | true 156 | 158 | executable 159 | 160 | 161 | 162 | 163 | 164 | 168 | maven-enforcer-plugin 169 | 1.0.1 170 | 171 | 172 | enforce-maven 173 | 174 | enforce 175 | 176 | 177 | 178 | 179 | ${project.java.version} 180 | 181 | 182 | 187 | 3.0.0 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 202 | 203 | org.springframework 204 | spring-beans 205 | ${spring.framework.version} 206 | 207 | 208 | org.springframework 209 | spring-context 210 | ${spring.framework.version} 211 | 212 | 213 | 215 | org.springframework 216 | spring-jdbc 217 | ${spring.framework.version} 218 | 219 | 220 | 224 | 225 | org.springframework.batch 226 | spring-batch-core 227 | ${spring.batch.version} 228 | 229 | 230 | org.springframework.batch 231 | spring-batch-infrastructure 232 | ${spring.batch.version} 233 | 234 | 235 | 236 | org.springframework.batch 237 | spring-batch-test 238 | ${spring.batch.version} 239 | test 240 | 241 | 242 | org.springframework 243 | spring-test 244 | ${spring.framework.version} 245 | test 246 | 247 | 248 | junit 249 | junit 250 | 4.10 251 | test 252 | 253 | 254 | -------------------------------------------------------------------------------- /hello-world-java/spring-batch-concept-chunk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/langmi/spring-batch-tutorials/274baf9074cc10161bc9fe6dd8e3d4a837af10d4/hello-world-java/spring-batch-concept-chunk.png -------------------------------------------------------------------------------- /hello-world-java/spring-batch-concept-job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/langmi/spring-batch-tutorials/274baf9074cc10161bc9fe6dd8e3d4a837af10d4/hello-world-java/spring-batch-concept-job.png -------------------------------------------------------------------------------- /hello-world-java/spring-batch-concept-step.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/langmi/spring-batch-tutorials/274baf9074cc10161bc9fe6dd8e3d4a837af10d4/hello-world-java/spring-batch-concept-step.png -------------------------------------------------------------------------------- /hello-world-java/spring-batch-tutorial-hello-world-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/langmi/spring-batch-tutorials/274baf9074cc10161bc9fe6dd8e3d4a837af10d4/hello-world-java/spring-batch-tutorial-hello-world-logo.png -------------------------------------------------------------------------------- /hello-world-java/src/main/java/de/langmi/spring/batch/tutorials/helloworld/HelloWorldTasklet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2011 Michael R. Lange . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.langmi.spring.batch.tutorials.helloworld; 17 | 18 | import org.springframework.batch.core.StepContribution; 19 | import org.springframework.batch.core.scope.context.ChunkContext; 20 | import org.springframework.batch.core.step.tasklet.Tasklet; 21 | import org.springframework.batch.repeat.RepeatStatus; 22 | 23 | /** 24 | * This is a Tasklet(step) implementation which prints out a friendly "Hello World!". 25 | * 26 | * In Spring Batch a Taskletstep is a simplified version of a Step, 27 | * without the chunk-oriented processing. 28 | * 29 | * @author Michael R. Lange 30 | * @see TaskletStep 31 | * @see Step 32 | * @see chunk-oriented processing 33 | */ 34 | public class HelloWorldTasklet implements Tasklet { 35 | 36 | /** {@inheritDoc} */ 37 | @Override 38 | public RepeatStatus execute(StepContribution contribution, 39 | ChunkContext chunkContext) throws Exception { 40 | 41 | // why not using println? because it makes testing harder, *nix and 42 | // windows think different about new line as in \n vs \r\n 43 | System.out.print("Hello World!"); 44 | 45 | return RepeatStatus.FINISHED; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /hello-world-java/src/main/resources/commons-logging.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Michael R. Lange . 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ######################################## 15 | # 16 | # logging configuration is only for a real simple spring batch 'hello world' example 17 | org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog -------------------------------------------------------------------------------- /hello-world-java/src/main/resources/simplelog.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Michael R. Lange . 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ######################################## 15 | # 16 | # logging configuration is only for a real simple spring batch 'hello world' example 17 | # loglevel = error to see the 'hello world' text only 18 | org.apache.commons.logging.simplelog.defaultlog=error 19 | -------------------------------------------------------------------------------- /hello-world-java/src/main/resources/spring/batch/job/hello-world-job.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | Simple Spring Batch Configuration 24 | 25 | - one tasklet step 26 | - prints out "Hello World!" 27 | - setup without database, uses in-memory JobRepository 28 | - not restartable 29 | 30 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 44 | 47 | 48 | 51 | 52 | 54 | 55 | -------------------------------------------------------------------------------- /hello-world-java/src/test/java/de/langmi/spring/batch/tutorials/helloworld/HelloWorldJobConfigurationManualTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012 Michael R. Lange . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.langmi.spring.batch.tutorials.helloworld; 17 | 18 | import java.io.ByteArrayOutputStream; 19 | import java.io.PrintStream; 20 | import org.junit.After; 21 | import static org.junit.Assert.assertEquals; 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | import org.springframework.batch.core.BatchStatus; 25 | import org.springframework.batch.core.Job; 26 | import org.springframework.batch.core.JobExecution; 27 | import org.springframework.batch.core.JobParameters; 28 | import org.springframework.batch.core.launch.JobLauncher; 29 | import org.springframework.context.ApplicationContext; 30 | import org.springframework.context.support.FileSystemXmlApplicationContext; 31 | 32 | /** 33 | * Testing a Spring Batch without any Spring utilities. 34 | * 35 | * @author Michael R. Lange 36 | */ 37 | public class HelloWorldJobConfigurationManualTest { 38 | 39 | /** Stream for catching System.out. */ 40 | private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); 41 | 42 | @Test 43 | public void testLaunch() throws Exception { 44 | // load ApplicationContext 45 | ApplicationContext context = new FileSystemXmlApplicationContext("src/main/resources/spring/batch/job/hello-world-job.xml"); 46 | // get job 47 | Job job = context.getBean(Job.class); 48 | // get job launcher 49 | JobLauncher jobLauncher = context.getBean(JobLauncher.class); 50 | // start job 51 | JobExecution jobExecution = jobLauncher.run(job, new JobParameters()); 52 | // assertion 53 | assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); 54 | // assert sysoutput 55 | assertEquals("Hello World!", outContent.toString()); 56 | } 57 | 58 | @Before 59 | public void setUpStreams() { 60 | // catch system out 61 | System.setOut(new PrintStream(outContent)); 62 | } 63 | 64 | @After 65 | public void cleanUpStreams() { 66 | // reset JVM standard 67 | System.setOut(null); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /hello-world-java/src/test/java/de/langmi/spring/batch/tutorials/helloworld/HelloWorldJobConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2011 Michael R. Lange . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.langmi.spring.batch.tutorials.helloworld; 17 | 18 | import java.io.PrintStream; 19 | import org.junit.After; 20 | import java.io.ByteArrayOutputStream; 21 | import static org.junit.Assert.*; 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.springframework.batch.core.BatchStatus; 26 | import org.springframework.batch.core.Job; 27 | import org.springframework.batch.core.JobExecution; 28 | import org.springframework.batch.core.JobParameters; 29 | import org.springframework.batch.core.launch.JobLauncher; 30 | import org.springframework.beans.factory.annotation.Autowired; 31 | import org.springframework.test.context.ContextConfiguration; 32 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 33 | 34 | /** 35 | * JobConfigurationTest, loads the Spring Batch Job definition and runs 36 | * the configured job. 37 | * 38 | * @author Michael R. Lange 39 | */ 40 | @ContextConfiguration(locations = {"classpath*:spring/batch/job/hello-world-job.xml"}) 41 | @RunWith(SpringJUnit4ClassRunner.class) 42 | public class HelloWorldJobConfigurationTest { 43 | 44 | @Autowired 45 | private Job job; 46 | @Autowired 47 | private JobLauncher jobLauncher; 48 | private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); 49 | 50 | /** Simple Launch Test. */ 51 | @Test 52 | public void launchJob() throws Exception { 53 | // launch the job 54 | JobExecution jobExecution = jobLauncher.run(job, new JobParameters()); 55 | 56 | // assert job run status 57 | assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); 58 | 59 | // assert sysoutput 60 | assertEquals("Hello World!", outContent.toString()); 61 | } 62 | 63 | @Before 64 | public void setUpStreams() { 65 | // catch system out 66 | System.setOut(new PrintStream(outContent)); 67 | } 68 | 69 | @After 70 | public void cleanUpStreams() { 71 | // reset JVM standard 72 | System.setOut(null); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /hello-world-java/src/test/java/de/langmi/spring/batch/tutorials/helloworld/HelloWorldTaskletTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012 Michael R. Lange . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package de.langmi.spring.batch.tutorials.helloworld; 17 | 18 | import java.io.ByteArrayOutputStream; 19 | import java.io.PrintStream; 20 | import org.junit.After; 21 | import static org.junit.Assert.assertEquals; 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | import org.springframework.batch.core.step.tasklet.Tasklet; 25 | import org.springframework.batch.repeat.RepeatStatus; 26 | 27 | /** 28 | * Simple test for {@link HelloWorldTasklet}. 29 | * 30 | * @author Michael R. Lange 31 | * @see JUnit test for system.out.println 32 | */ 33 | public class HelloWorldTaskletTest { 34 | 35 | /** Stream for catching System.out. */ 36 | private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); 37 | private final Tasklet tasklet = new HelloWorldTasklet(); 38 | 39 | @Test 40 | public void testExecute() throws Exception { 41 | assertEquals(RepeatStatus.FINISHED, tasklet.execute(null, null)); 42 | // assert sysoutput 43 | assertEquals("Hello World!", outContent.toString()); 44 | } 45 | 46 | @Before 47 | public void setUpStreams() { 48 | // catch system out 49 | System.setOut(new PrintStream(outContent)); 50 | } 51 | 52 | @After 53 | public void cleanUpStreams() { 54 | // reset JVM standard 55 | System.setOut(null); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 20 | 21 | 4.0.0 22 | 23 | de.langmi.spring.batch.tutorials 24 | parent 25 | 1.0-SNAPSHOT 26 | pom 27 | 28 | spring batch tutorials parent 29 | https://github.com/langmi/spring-batch-tutorials 30 | 31 | Spring Batch Tutorials parent project for convenient build all feature 32 | 33 | 34 | hello-world-java 35 | hello-world-groovy 36 | 37 | 38 | 39 | 40 | Apache 2 41 | http://www.apache.org/licenses/LICENSE-2.0.txt 42 | manual 43 | 44 | Declared 'manual' distribution, because there are no plans 45 | to upload the project to a maven repository. 46 | 47 | 48 | 49 | 50 | 51 | 52 | michael 53 | Michael R. Pralow 54 | me@michael-pralow.de 55 | 56 | architect 57 | developer 58 | 59 | +1 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /spring-batch-tutorials-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/langmi/spring-batch-tutorials/274baf9074cc10161bc9fe6dd8e3d4a837af10d4/spring-batch-tutorials-logo.png --------------------------------------------------------------------------------