I released five new sample lessons from my Test With Spring course: Introduction to Spock Framework

Spring Batch Tutorial: Getting the Required Dependencies With Maven

The first part of my Spring Batch tutorial specified the term batch job, explained why we should use Spring Batch, and identified the basic building blocks of a Spring Batch job.

Before we can move on and see Spring Batch in action, we have to get the required dependencies. This blog post describes how we can get these dependencies with Maven.

Let’s start by taking a look at the modules provided by Spring Batch.

If you are not familiar with Spring Batch, you should read the following blog post before you continue reading this blog post:

Introduction to the Modules of Spring Batch

Spring Batch provides the following modules:

  • The spring-batch-infrastructure module contains the common readers and writers, and provides services for application developers and the core module.
  • The spring-batch-core module contains the classes that are required to launch and control Spring Batch jobs.
  • The spring-batch-test module provides support for writing automated tests to Spring Batch jobs.
  • The spring-batch-integration module helps us to integrate Spring Batch with Spring Integration.

Let’s move on and find out how we can get the required dependencies when we are writing a “normal” Spring application.

Getting the Dependencies of a Spring Application

When we are writing Spring Batch jobs by using Spring Framework, we have to get the following dependencies:

  • The JDBC driver provides a database specific implementation of the JDBC API. We use the H2 in-memory database because it makes our example application easier to run.
  • Liquibase. We use Liquibase for creating the database of our example application when the Spring container is started.
  • The datasource provides database connections to our application. We use the HikariCP datasource because it is the fastest datasource on this planet.
  • The JPA Provider implements the Java Persistence API. We use Hibernate because it is the most common JPA provider.
  • Spring Data JPA hides the used JPA provider behind its repository abstraction.
  • The dependencies required by a Spring web application. These dependencies include the following Spring modules: spring-aspects, spring-context-support, and spring-webmvc. We also need to get the Servlet API. We need these dependencies because this is the “easiest” way to start a Spring container which ensures that our scheduled jobs are run.
  • Spring Object/XML Mapping support provides support for converting XML documents into objects and vice versa. We need this support when we read information from XML files and write information into XML files.
  • Spring Batch Core contains the classes that are required to launch and control Spring Batch jobs. Also, it includes the spring-batch-infrastructure module.

When we are writing Spring applications, we can get the required dependencies by using one of these two options:

  1. We can manage the dependency versions by using the Spring IO Platform.
  2. We can use the traditional way and manage the dependency versions manually.

Let’s find out how we can get the required dependencies with the Spring IO Platform.

Using the Spring IO Platform

We can get the required dependencies by following these steps:

  1. Enable the Spring IO Platform.
  2. Configure the required dependencies in the pom.xml file.

First, we can enable the Spring IO Platform by adding the following XML into our POM file:

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>io.spring.platform</groupId>
			<artifactId>platform-bom</artifactId>
			<version>2.0.1.RELEASE</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

Second, after we have enabled the Spring IO Platform, we don’t have to worry about dependency versions because the Spring IO Platform takes care of that. This means that we can get the required dependencies by adding the following XML into the dependencies section of our POM file:

<!-- Database -->
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>
 
<!-- Liquibase -->
<dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-core</artifactId>
</dependency>
 
<!-- DataSource -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
</dependency>
         
<!-- JPA Provider -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
</dependency>
 
<!-- Spring -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>
 
<!-- Spring Web -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
</dependency>
 
 <!-- Spring Object/XML Mapping support -->
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-oxm</artifactId>
 </dependency>
 
<!-- Spring Batch -->
<dependency>
    <groupId>org.springframework.batch</groupId>
    <artifactId>spring-batch-core</artifactId>
</dependency>

Let’s move on and find out how we can manage our dependency versions manually.

Using the Traditional Way

If we want to use the traditional way, we have to manage our dependency versions “manually”. In other words, we need specify the version numbers of all dependencies. We can do this by adding the following dependency declarations into the dependencies section of our pom.xml file:

<!-- Database -->
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
	<version>1.4.190</version>
</dependency>
 
<!-- Liquibase -->
<dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-core</artifactId>
	<version>3.4.2</version>
</dependency>
 
<!-- DataSource -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
	<version>2.4.3</version>
</dependency>
         
<!-- JPA Provider -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
	<version>4.3.11.Final</version>
</dependency>
<!-- Spring Data JPA -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
	<version>1.9.2.RELEASE</version>
</dependency>
 
<!-- Spring -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
	<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
	<version>4.2.4.RELEASE</version>
</dependency>
 
<!-- Spring Web -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <scope>provided</scope>
	<version>3.1.0</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
	<version>4.2.4.RELEASE</version>
</dependency>

 <!-- Spring Object/XML Mapping support -->
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-oxm</artifactId>
	 <version>4.2.4.RELEASE</version>
 </dependency>
 
<!-- Spring Batch -->
<dependency>
    <groupId>org.springframework.batch</groupId>
    <artifactId>spring-batch-core</artifactId>
	<version>3.0.6.RELEASE</version>
</dependency>

We are now aware how we can get the required dependencies of a normal Spring application. However, we might want to use Spring Boot. Let’s find out how we can get the required dependencies of a Spring Boot application.

Getting the Dependencies of a Spring Boot Application

We can get the required dependencies by following these steps:

  1. Inherit the default settings from the spring-boot-starter-parent project.
  2. Configure the required dependencies.

First, we can inherit the default settings from the spring-boot-starter-parent project by adding the following XML into our pom.xml file:

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.3.2.RELEASE</version>
</parent>

Second, after we have inherited the default settings from the spring-boot-starter-parent project, we need to configure the required dependencies. When we do this, we don’t have to worry about dependency versions because Spring Boot takes care of that. We need to get the following dependencies:

  • The spring-boot-starter-batch dependency provides the dependencies that are required by Spring Batch.
  • The spring-boot-starter-data-jpa dependency provides the dependencies that are required Spring Data JPA.
  • Spring Object/XML Mapping support provides support for converting XML documents into objects and vice versa. We need this support when we read information from XML files and write information into XML files.
  • Liquibase. We use Liquibase for creating the database of our example application when the Spring container is started.
  • The JDBC driver provides a database specific implementation of the JDBC API. We use the H2 in-memory database because it makes our example application easier to run.

We can get these dependencies by adding the following dependency declarations into the dependencies section of our pom.xml file:

<!-- Spring Batch -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-batch</artifactId>
</dependency>

<!-- Spring Data JPA -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Spring Object/XML Mapping support -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-oxm</artifactId>
</dependency>

<!-- Liquibase -->
<dependency>
	<groupId>org.liquibase</groupId>
	<artifactId>liquibase-core</artifactId>
</dependency>

<!-- Database -->
<dependency>
	<groupId>com.h2database</groupId>
	<artifactId>h2</artifactId>
</dependency>

Let’s summarize what we learned from this blog post.

Summary

This blog post has taught us three things:

  • We learned to get the dependencies of a normal Spring application.
  • We know how we can get the dependencies of a Spring Boot application.
  • If we get the required dependencies by using the Spring IO Platform or inheriting the default settings from the spring-boot-starter-parent project, we don’t have to worry about dependency versions.

The next part of this tutorial describes how we can get the required dependencies with Gradle.

P.S. You can get the example applications of this blog post Github: Spring example and Spring Boot example.

About the Author

Petri Kainulainen is passionate about software development and continuous improvement. He is specialized in software development with the Spring Framework and is the author of Spring Data book.

About Petri Kainulainen →

13 comments… add one
  • Thanks Petri for another insightful blog post.

    Looking forward to the rest of this new series – I remember trying to use Spring batch a couple of years back and found it very complicated. As I had a deadline ended up abandoning it. So am hoping to learn it finally though this blog series.

    I do find it odd that you are using JPA (Hibernate) for a batch process – I always preferred using JDBC directly for batch process. But am sure this is an opportunity for me to broaden my horizon and learn more :)

    I enjoyed your series on Spring Data which inspired me to buy your book.
    Am excited to see this where new series leads to.

    Best wishes,
    SGB

    Reply
    • Hi,

      Thank your for your kind words. I really appreciate them.

      I remember trying to use Spring batch a couple of years back and found it very complicated. As I had a deadline ended up abandoning it. So am hoping to learn it finally though this blog series.

      I have heard similar comments from my colleagues as well, and that is why I decided to write this tutorial.

      I do find it odd that you are using JPA (Hibernate) for a batch process – I always preferred using JDBC directly for batch process. But am sure this is an opportunity for me to broaden my horizon and learn more :)

      This is a good point. I have to confess that typically I use JDBC as well (for batch processes), but I decided to cover both JDBC and JPA because there are a few situations when it makes sense to use JPA. In other words, sometimes the benefits of using JPA are so high that it makes sense to take a performance hit.

      Reply
  • Hi

    The following dependency in your article , is wrong because till now only 1.4.191 , is latest version for h2 data base ,but you mentioned the version as , 1.4.90 , so can you please check

    com.h2database
    h2
    1.4.90

    Reply
    • Hi,

      If you specify your dependencies manually, you should naturally use the newest versions. However, if you use Spring IO Platform or Spring Boot, your best option is to not specify dependency versions and use the versions that are guaranteed to work (provided by parent or starter POMs).

      Reply
      • Hi

        I agree the automatically downloading dependencies using sping IO , am just telling you that you mentioned wrong version number for the dependency , as 1.4.90 , am just telling you it is 1.4.191 , please observe the numbers and correct in your article

        Reply
        • Hi,

          This post uses the dependency versions that provided by the Spring IO Platform 2.0.1.RELEASE because this way I can guarantee that they are working with each other. Because the Spring IO Platform 2.0.1.RELEASE uses H2 1.4.190, this article will use it as well.

          Reply
          • lol. Hilarious!
            I think Ramesh is saying that there is a typo in the section “Tradition Way”.
            For the h2 dependency, in your pom file, you have listed version 1.4.90 instead of 1.4.190.

            90 vs 190.

          • Oops. I fixed it. Thank you for pointing this out.

  • Hi Petri,
    I tried running your spring boot batch code (excelFileToDatabaseJob) and seeing the below exception
    Caused by: java.lang.IllegalArgumentException: Sheet index (1) is out of range (0..0)
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.validateSheetIndex(XSSFWorkbook.java:1158) ~[poi-ooxml-3.11.jar:3.11]
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.getSheetAt(XSSFWorkbook.java:934) ~[poi-ooxml-3.11.jar:3.11]
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.getSheetAt(XSSFWorkbook.java:106) ~[poi-ooxml-3.11.jar:3.11]
    at org.springframework.batch.item.excel.poi.PoiItemReader.getSheet(PoiItemReader.java:47) ~[spring-batch-excel-0.5.0-SNAPSHOT.jar:na]

    I created a new project that reads an excel and processes it using spring-batch-excel code and seeing the same exception as well. Have you seen this happening?

    Reply
    • Hi Sharmila,

      I haven’t seen that exception. However, it looks like the spreadsheet has an empty row somewhere, and this is why the exception is thrown.

      Did you modify the spreadsheet or replace it with some other spreadsheet? Also, if you opened it with Excel, Excel might have modified it for you :| The reason why I ask this is that I cannot reproduce this with my version. :(

      Reply

Leave a Comment