6

I have a maven multi module project designed like the first answer in following SO post: Multi-module maven with Spring Boot

Now I want a common maven module that can contain some models to be used by multiple microservices. If I make this common project as a child of the first level parent pom (so that all dependencies injected by boot like jpa, jackson etc are available to common), then STS/Spring is detecting it as a boot application and complains about no Main class on maven build.

Can someone suggest how I can achieve this?

Current Code:

parent pom.xml: (Only relevant parts included)

    <project>
    <name>...</name>
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <packaging>pom</packaging>
    <version>...</version>
    <parent>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-parent</artifactId>
        <version>Brixton.M3</version>
        <relativePath />
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    </project>

child (common module) pom.xml (only relevant parts), not to be boot app:

    <project>
    <artifactId>...</artifactId>
    <version>...</version>
    <name>...</name>

    <parent>
        <groupId>...</groupId>
        <artifactId>...</artifactId>
        <version>...</version>
    </parent>

    </project>
Paul Verest
  • 60,022
  • 51
  • 208
  • 332
Shashank Singhal
  • 170
  • 1
  • 2
  • 9

3 Answers3

11

I don't have all the details regarding your project but my best guess is that the spring-boot-maven-plugin is defined on the parent (or you are using the spring-boot-starter-parent in your root pom). This effectively ask the build to package your module as a Spring Boot app (which is not what you want).

STS probably looks for that hint to figure out if a module contains a Spring Boot application or not. Maybe it would be nicer if it looks for a main class annotated with @EnableAutoConfiguration (or SpringBootApplication).

You can fix the problem easily (from the build side) by specifying the skip property of the repackage goal

  <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
          <skip>true</skip>
    </configuration>
  </plugin>

If STS still picks up the module as a Spring Boot app, I'd create an issue in their tracker

Stephane Nicoll
  • 31,977
  • 9
  • 97
  • 89
  • 2
    Thanks for the help. I tried as you suggested but it did now help. Added following section to child pom: ` org.springframework.boot spring-boot-maven-plugin repackage true ` This however reduced my build time as the common modules are not repackaged as executable jars – Shashank Singhal Dec 21 '15 at 12:50
  • I am afraid, I can't help you without more details. I am just guessing at this point. – Stephane Nicoll Dec 21 '15 at 14:11
  • Thanks a lot, it was a resolution for my problem with spring-boot not seeing mainClass property :D – argh Nov 10 '16 at 14:12
0

Normally, Spring Boot won't start a web container if it's not present in the module. I would suggest you to analyse your dendencies using the command

mvn dependency:tree 

One more brute-force way of ensuring is use this configuration in your application.properties

spring.main.web-environment=false
R K Punjal
  • 1,445
  • 1
  • 15
  • 20
0

Here are two ways to fix this:

  1. You can add the skip property like @Stephane Nicoll mentioned. However, this will completely ignore the test cases inside that module. https://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/it-skip.html
  2. Another option is to add a classifier property to make a separate executable jar out of this module. https://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/repackage-classifier.html

    <executions>
              <execution>
                <id>repackage</id>
                <goals>
                  <goal>repackage</goal>
                </goals>
                <configuration>
                  <classifier>exec</classifier>
                </configuration>
              </execution>
    

This fix will make sure the dependent module get its required jar and the source module will still be an executable one.

jwpfox
  • 5,124
  • 11
  • 45
  • 42