215

Is there a specific recommended approach to the inclusion of the spring-boot parent pom into projects that already have a required parent POM?

What do you recommend for projects that need to extend from an organizational parent (this is extremely common and even something many/most projects published to Maven central depending on the feeder repos they come from). Most of the build stuff is related to creating executable JARs (e.g. running embedded Tomcat/Jetty). There are ways to structure things so that you can get all the dependencies without extending from a parent (similar to composition vs. inheritance). You can't get a build stuff that way though.

So is it preferable to include all of the spring-boot parent pom inside of the required parent POM or to simply have a POM dependency within the project POM file.

Other options?

TIA,

Scott

Scott C.
  • 3,672
  • 4
  • 18
  • 20

3 Answers3

198

You can use the spring-boot-starter-parent like a "bom" (c.f. Spring and Jersey other projects that support this feature now), and include it only in the dependency management section with scope=import.That way you get a lot of the benefits of using it (i.e. dependency management) without replacing the settings in your actual parent.

The 2 main other things it does are

  1. define a load of properties for quickly setting versions of dependencies that you want to override
  2. configure some plugins with default configuration (principally the Spring Boot maven plugin). So those are the things you will have to do manually if you use your own parent.

Example provided in Spring Boot documentation:

<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.1.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
Michael
  • 41,989
  • 11
  • 82
  • 128
Dave Syer
  • 56,583
  • 10
  • 155
  • 143
  • 1
    I am guessing this does pull in the plugins - shade etc? – chrislovecnm Jan 07 '15 at 22:58
  • 4
    No. Read the link: "you can still keep the benefit of the dependency management (but not the plugin management)". – Dave Syer Jan 08 '15 at 09:08
  • @DaveSyer can you please confirm if it is possible to exclude dependencies in the manner shown above? I can't seem to get that to work. – btiernay Jan 14 '15 at 01:19
  • Yes it's possible (normal maven rules for dependency resolution apply - they can be a bit confusing). – Dave Syer Jan 14 '15 at 06:45
  • 1
    @DaveSyer Please clarify: 1: When I have my custom `project-parent` I could add `spring-boot-starter-parent` to this `project-parent` - is it ok? Do I also need `spring-boot-dependencies` in such situation? 2: Normal spring-boot project I run using spring-boot:run. How to run project with different parent pom? – jsosnowski Aug 18 '15 at 08:10
  • 1
    The code snippet above is sufficient to get the dependency management features. If you want plugins (like `spring-boot:run`) you need to confute those separately. You can copy paste from the Boot parent if you want. – Dave Syer Aug 22 '15 at 15:17
  • Sorry, old question, I know. If you import the spring boot dependencies like this, is there a way to reference the element in spring-boot-dependencies in my poms? I have a submodule with a dependency on activemq-camel and I'd like it to be pegged to the same version as activemq in spring-boot-dependencies. – UrLicht Sep 02 '15 at 16:29
  • 1
    No, there is not. It has to be a parent pom to inherit the ``. – Dave Syer Sep 08 '15 at 09:34
  • 3
    I know it's an old thread but it helped me a lot, thanks. I ended up reading about this mechanism at the source https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies. It explains a lot. – bazeusz Jan 29 '16 at 16:50
  • Important to note that properties are not inherited with the import of the bom as Dave said. You also have to copy the properties for plugin versions from spring-boot-starter-dependencies. At least that's what I found when transforming a project using Spring Boot 1.5.21 to multi module. – Nils Rommelfanger Aug 26 '19 at 16:14
  • Variables from spring boot parent pom such as `tomcat.version` are not available in effective pom, so that all the props declared in properties section are not effective. Is there any solution for this? – Paramesh Korrakuti May 12 '20 at 11:16
  • The solution is to redeclare them manually in your parent pom, or use the parent pom from Spring Boot. – Dave Syer May 12 '20 at 16:52
55

Update 2022-05-29 with 1.5.9.RELEASE.

I have full code and runable example here https://github.com/surasint/surasint-examples/tree/master/spring-boot-jdbi/9_spring-boot-no-parent (see README.txt to see that you can try)

You need this as a basic

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

But that is not enough, you also need explicitly define goal for spring-boot-maven-plugin (If you use Spring Boot as parent, you do not have to explicitly define this)

    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${springframework.boot.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>

Otherwise you cannot build as executable jar or war.

Not yet, if you are using JSP, you need to have this:

<properties>    
  <failOnMissingWebXml>false</failOnMissingWebXml>
</properties>

Otherwise, you will get this error message:

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project spring-boot-09: Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executi
ng in update mode) -> [Help 1]

NO NO , this is still not enough if you are using Maven Profile and Resource Filter with Spring Boot with "@" instead of "${}" (like this example https://www.surasint.com/spring-boot-maven-resource-filter/). Then you need to explicitly add this in

    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>

And this in

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.7</version>
            <configuration>
                <delimiters>
                    <delimiter>@</delimiter>
                </delimiters>
                <useDefaultDelimiters>false</useDefaultDelimiters>
            </configuration>
        </plugin>

See the example in the link https://www.surasint.com/spring-boot-with-no-parent-example/.

Surasin Tancharoen
  • 5,520
  • 4
  • 32
  • 40
3

As per Surasin Tancharoen's answer, you may also want to define maven surefire plugin

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>${maven-surefire-plugin.version}</version>
        </plugin>

and possibly include fail-fast plugin

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>${maven-failsafe-plugin.version}</version>
        <executions>
            <execution>
                <goals>
                    <goal>integration-test</goal>
                    <goal>verify</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
trenunu
  • 63
  • 5
  • Including maven-surefire-plugin was a life saver for me. Without this Spring Boot would not load application context for integration tests. – abbas Dec 18 '22 at 11:25