Spring Batch

Execute with Test Resources

To execute a Spring Batch programm with test resource using Maven the exec.classpathScope needs to be set on the mvn command.

mvn exec:java -Dexec.classpathScope="test"

Output

No Output

Sometimes there is nothing to be written as there is no output. A NoopItemWriter can be created like this:

public class NoopItemWriter<T> implements ItemWriter<T> {
    
    @Override
    public void write(List<? extends T> items) throws Exception {
        // nothing to do here
    }

}

The item writer is added to the launch context file.

<beans:bean id="itemWriter" class="one.time.util.NoopItemWriter" />

Input

Declare Comment Lines

Depending on the system and file comments may start with very different characters. These can be specified in the item writer (if it is supported by the implementation) like this:

<beans:property name="comments">
    <beans:array value-type="java.lang.String">
        <beans:value>#</beans:value>
        <beans:value>;</beans:value>
        <beans:value>!</beans:value>
    </beans:array>
</beans:property>

Skipping Empty Lines

The default reader implementation does not skip empty lines. There is a reader implementation from Robert Kasanicky where empty lines are treated as comments.

The implementation can be found here.

Skipping First Lines

CSV files often start with the column names. Generally these must be skipped when processing the file. If you are using the FlatFileItemReader you can just add a property to your itemReader bean like this:

<beans:property name="linesToSkip" value="1" />

CSV File Input

Reading a delimited file with Spring Batch is a combination of using a file item reader, line mapper and line tokenizer.

<beans:bean id="itemReader" class="one.time.util.ExtFlatFileItemReader">
	    <beans:property name="linesToSkip" value="1" />
		<beans:property name="resource" value="${data.location}" />
		<beans:property name="lineMapper">
		    
			<beans:bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
				<beans:property name="lineTokenizer">
					<beans:bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                                            <!-- field delimiter of your csv file -->
					    <beans:property name="delimiter" value="," />
                                                <!-- property names of your bean , the order of the names is important -->
						<beans:property name="names" value="id,street,housenumber" />
					</beans:bean>
				</beans:property>
				<beans:property name="fieldSetMapper">
                                        <!-- the fields are mapped to properties of your bean -->
					<beans:bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                                                <!-- the model your data is mapped to -->
						<beans:property name="targetType" value="my.model.Location" />
					</beans:bean>
				</beans:property>
			</beans:bean>
			
		</beans:property>
</beans:bean>

Tab Delimited Values

To declare the tab character as a delimiter “\t” cannot be specified. Instead use the Java constant from the Spring framework.

  <beans:property name="lineTokenizer">
    <beans:bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
      <!-- field delimiter of your csv file -->
      <beans:property name="delimiter">
        <util:constant static-field="org.springframework.batch.item.file.transform.DelimitedLineTokenizer.DELIMITER_TAB"/>
      </beans:property>
    </beans:bean>
  </beans:property>

Don't forget to add the namespance to the head of the xml file.

<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:batch="http://www.springframework.org/schema/batch"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="
          http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
          http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

Create Jar with Dependencies

To embed all dependencies and create an executable jar the pom.xml must be extended by the maven-assenbly-plugin.

    <build>
		<plugins>
			<plugin>
				<artifactId>maven-assembly-plugin</artifactId>
				<configuration>
					<archive>
						<manifest>
							<mainClass>
								org.springframework.batch.core.launch.support.CommandLineJobRunner
							</mainClass>
						</manifest>
					</archive>
					<descriptorRefs>
						<descriptorRef>jar-with-dependencies</descriptorRef>
					</descriptorRefs>
				</configuration>
			</plugin>
		</plugins>
	</build>

Create the jar with executing the following line on the command line

mvn clean compile assembly:single

Execute the program with

java -jar program-jar-with-dependencies.jar launch-context.xml jobid