Making Spring Batch Groovy

Rik Scarborough Java, Microservices, Spring, Spring Batch, Technology Snapshot, Tutorial Leave a Comment

Here at Keyhole, we are very fond of Spring Batch. In many Java Enterprise environments, there is still a big need for automating moving data around. Spring Batch gives us a great head start on creating these batch processes.

Note: if you’re in the area on Wednesday night (8/5/15), check out Keyhole Managing Partner David Pitt’s Spring Batch presentation at the Kansas City Spring User Group Meeting.

I’ve written several times now about using Groovy as a tool for rapidly developing easy to maintain software. It is my opinion that the fact that Groovy is essentially Java and even generates classes that can be run in the JVM, is one of its strongest points.

Jonny recently wrote a blog post about replacing the XML configuration for Spring Batch with JavaConfig. Since anything you can do in Java, you should be able to do in Groovy, I began to wonder if you can make Spring Batch Groovy.

Groovy Configuration

Here is the Groovy Configuration class I wrote to see.

Note: you can write this with or without the semicolons as you see fit. I did it without so you can tell it’s Groovy code.

package com.keyholesoftware.example

import org.springframework.batch.core.Job
import org.springframework.batch.core.Step
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory
import org.springframework.batch.core.launch.support.RunIdIncrementer
import org.springframework.batch.item.ItemReader
import org.springframework.batch.item.ItemProcessor
import org.springframework.batch.item.ItemWriter
import org.springframework.batch.item.NonTransientResourceException
import org.springframework.batch.item.ParseException
import org.springframework.batch.item.UnexpectedInputException
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

import groovy.json.*

/**
 *
 * @author rik
 */
@Configuration
@EnableAutoConfiguration
@EnableBatchProcessing
public class GroovyExampleConfig {

    @Autowired
    private JobBuilderFactory jobs

    @Autowired
    private StepBuilderFactory steps

    @Bean
    public Job job() throws Exception {
        return jobs.get("groovyExample").start(exampleStep()).build()
    }

    @Bean
    public Step exampleStep() {
        return steps.get("exampleStep")
        .<String, String> chunk(5)
        .reader(new ItemReader<String>() {
                boolean finished = false
                @Override
                public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
                    if(!finished) {
                        finished = true
                        return new File("example.txt").text
                    } else {
                        return null
                    }
                }
            })
        .processor(new ItemProcessor<String, String>() {
                @Override
                public String process(String item) throws Exception {
                    return JsonOutput.toJson([text: item])
                }
            })
        .writer(new ItemWriter<String>() {
                @Override
                public void write(List<? extends String> items) throws Exception {
                    File file = new File("exampleJson.txt")
                    items.each { line ->
                        file << line
                    }
                }
            })
        .build()
    }
}

This code opens a file and reads the entire text in the Reader. Wraps that text in JSON in the Processor, and then writes it back to a file in the writer. Notice I use the Groovy additions to the Java language in each of these. Spring Batch comes equipped with an excellent set of readers and writers that could accomplish the same thing, but sometimes, for maintenance sake, you just want to do something simple.

The Spring Boot main file I used is here.

package com.keyholesoftware.example

import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
/**
 *
 * @author rik
 */
@SpringBootApplication
public class GroovyBatch {

    public static void main(String[] args) throws Exception {
        System.exit(SpringApplication.exit(SpringApplication.run(
                    GroovyExampleConfig.class, args)))
    }
}

Groovy has many features that help you quickly develop an application, but unlike some other languages that I will leave unnamed, the trade off is not creating hard to maintain code.

Instead of simply writing the results out in the example I used, the JSON output could be uploaded to the Microservices that Keyhole is developing for you. Groovy has great features for communicating over a RESTful interface and would be great way for your batch processes to communicate with the Services.

I hope this gives you an idea of what you can accomplish by combining these technologies. Don’t forget to add Spock test classes and hopefully cut down on any future maintenance headaches.

Good Coding.

— Rik Scarborough, asktheteam@keyholesoftware.com


About the Author
Rik Scarborough

Rik Scarborough

Twitter

Rik Scarborough is a Kansas City-based software developer on the Keyhole Software team. He specializes in Enterprise Application Development using Java, Web Application Development, Spring Batch, Google’s Appengine, Google Web Toolkit (GWT), and Groovy. Also, a student of conversational American Sign Language.


Share this Post

Leave a Reply