14
votes

I have a small Spring Boot application which I must adapt to use a custom parent. Google finds lots of examples of how to migrate to Spring Boot, but I am at a loss as to migrate from Spring Boot (which I barely know to begin with).

The reasons

To make things short, this application was developed as a kind of a proof-of-concept and the developer chose state-of-the-art technologies.

Now, this application will keep on living and we need to integrate it in our framework. As a Maven project, it should therefore inherit one of our common parent, though it is my understanding Spring Boot projects should inherit from the Spring Boot starter parent POM.

[Edit] I was incorrect: it is possible to use Spring Boot without the parent POM. Removing Spring Boot is therefore not an obligation, but our parent POM includes its own version management, which obliges me to override several versions included in the starter.

Why we need to inherit from our parent

We have an enterprise framework used across all our projects. To make things easier, we manage versions of many frameworks in our parent POM. Some examples where these versions conflict with the ones from spring-boot-dependencies in our little batch project:

  • Spring framework (in-house: 3.2.4; Spring Boot 1.2.2: 4.1.5)
  • Spring Batch (ih: 2.2.0; sb: 3.0.3)
  • Velocity (ih: 1.5; sb: 1.7)
  • Junit (ih: 4.11; sb: 4.12)
  • ... (we manage about 90 versions)

I am obviously not at liberty to upgrade those versions. Please keep in mind this framework is used across many projects and any change could have dramatic and uncontrolled consequences.

Additional context

The objective is to get a little Spring batch application. It must take some input from the command line and return a 12 exit code if execution fails. Below is the core of the launcher but I am open to any better way to do it.

Our batch launcher class

If totally abandoning Spring Boot, I would need to adapt this launcher class but, being mostly used to XML Spring contexts, I find this a bit difficult.

// ...
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan("my.config.package")
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        // ...
        SpringApplication app = new SpringApplication(Application.class);
        app.setWebEnvironment(false);
        final Map<String, Object> maps = new HashMap<>();
        maps.put("input", "file:" + inputPath);
        app.setDefaultProperties(maps);
        ConfigurableApplicationContext ctx = app.run(args);

        JobExecutionSavingListener listener = ctx.getBean(JobExecutionSavingListener.class);

        final JobExecution jobExecution = listener.getJobExecution();
        if (jobExecution.getExitStatus() != ExitStatus.COMPLETED) {
            System.exit(12);
            return;
        }
        System.exit(0);
    }
}

The question

What is the best way to change my code to adapt my Spring Batch application so that I could use my own Maven parent?

2
Your understanding is wrong... You can still have a Spring Boot application without having to extend the parent as explained here. Just do that and be done with it. Just include the bom instead of the parent, you can use your own thing as a parent. I don't really get the starter class (that cuold be simplified). But I would strongly suggest not to remove spring boot, add the bom, extend your own parent and be done.M. Deinum
@M.Deinum This is really useful. I did not know of the <scope>import</scope>. I edited the question to match this new information. Maybe you could turn your comment into an answer, as it supplies the main elements of the answer.Chop
What versions are you managing? Also what framework versions are you using (you might run into issues with older versions not working with SPring Boot). So please add the versions and maybe relevant information from the parent... (at least group/artifactid would help).M. Deinum
@M.Deinum We have a quite comprehensive entreprise framework. Batches are a new addition to it. We have dependency management for Spring (us: 3.2.4, Spring Boot 1.2.2: 4.1.5), Velocity (u:1.5, sb:1.7)... I have 90 versions declared in the POM...Chop
You might (and probably will) run into trouble with at least the Spring Framework version as that might not work with Spring Boot, I would suggest at least upgrading to the latest Spring 3.2 version (and preferably a 4.x version). Spring Batch should work with those versions nonetheless so that isn't a problem. You are aware of the fact that support for 3.2 will be dropped as soon as Spring 4.2 sees the day of light?!M. Deinum

2 Answers

6
votes

You can use Spring Boot with or without using the spring-boot-starter-parent as a parent for your project. This is explained in this section of the Spring Boot Reference Guide.

Adding this to your project poms still lets you use Spring Boot and have your own parent.

<dependencyManagement>
     <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.2.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Now you can just define your own parent. Adding the following dependency should give you all the needed jars for running Spring Batch.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-batch</artifactId>
    </dependency>
</dependencies>

One of the drawbacks of not (being able to) using the Spring Boot starter as a parent is that if you need specific versions of a library you will need to include all the dependencies. When using it as a parent it would be as easy as specifing a property (i.e. spring-batch.version) with a version.

0
votes

You can still use Spring Boot to use Spring Batch, in fact it is the recommended approach.

Also, Spring Boot projects don't need to inherit from any parent pom, they just need to include the dependency to the spring boot library in your pom.

There is a very nice and simple example here:

Spring Batch example

You should understand that the only "special" thing about Spring Boot is that it was created to run standalone applications with the minimum amount of spring configuration unlike the traditional spring-web that was created to be run on a server.

I also forgot to add that you can still use XML configuration instead of a Java configuration approach if you feel more comfortable with it.