Spring Boot Maven Plugin - No BOOT-INF directory

In my case I'm using spring boot 2.X and I declared the spring-boot-maven-plugin after the maven-dependency-plugin (which I used to unpack and create exploded app in Docker) and it must be before the unpack, makes sense, it was unpacking before the spring boot maven plugin executed. Next time I'll declare it first thing in the plugin chain, lost more than 1 hour on this. Hope it helps someone.

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>${spring.boot.mainClass}</mainClass>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>unpack</id>
                    <phase>package</phase>
                    <goals>
                        <goal>unpack</goal>
                    </goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>${project.groupId}</groupId>
                                <artifactId>${project.artifactId}</artifactId>
                                <version>${project.version}</version>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

The answer above with

<layout>MODULE</layout>

does not work anymore, this is because layout element is deprecated in Spring Boot 2.x. I am using Spring Boot 2.0.x, I found this helpful comment on github:

Support for the module layout was removed in Spring Boot 2.0 having been deprecated in 1.5. Unfortunately, the updates to the Maven Plugin's documentation were missed so we can use this issue to sort that out. You should use a custom LayoutFactory instead.

But as I did not want to implement LayoutFactory I tried this second solution below that actually repackage and creates an extra jar with a classifier given name:

This is due to the change in layout of executable jars in Spring Boot 1.4. Application classes are now packaging in BOOT-INF/classes. Your client module depends on the repackaged, fat jar of your web module. Due to the new layout that means that the client module can no longer load the web module's classes. If you want to use your web module as a dependency, you should configure Boot's repackaging to apply a classifier to the fat jar. For example:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                    <configuration>
                        <classifier>exec</classifier>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Doing so will allow other modules to depend on the original jar that does not embed the module's dependencies and has the classes at the root of the jar.

One original jar have the same structure as I wanted like

com.my-package.foo.bar
META-INF

and the second classifier have the newer structure with BOOT-INF/ etc.


The solution was to add the MODULE layout for the plugin in the pom.xml file

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <layout>MODULE</layout>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>