Spring Boot Maven plugin

[Updated: Jan 12, 2017, Created: Dec 8, 2016]

Spring boot framework provides a maven plugin (spring-boot) which has following useful goals:

  • spring-boot:run to run our boot application in the exploded form.
  • spring-boot:repackage to package executable jar and war files.

Let's explore the plugin with an example.

Adding the plugin in pom.xml

<project ..>
  ......
 <groupId>com.logicbig.example</groupId>
 <artifactId>boot-mvn-plugin-example</artifactId>
 <version>1.0-SNAPSHOT</version>

 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.4.2.RELEASE</version>
 </parent>
 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>1.4.2.RELEASE</version>
   </plugin>
  </plugins>
 </build>

</project>


Listing the goals

Let's run mvn help:describe at the location where we created our pom.xml

D:\boot-mvn-plugin-example> mvn help:describe -Dplugin=spring-boot
  .....
[INFO] org.springframework.boot:spring-boot-maven-plugin:1.4.2.RELEASE

Name: Spring Boot Maven Plugin
Description: Spring Boot Maven Plugin
Group Id: org.springframework.boot
Artifact Id: spring-boot-maven-plugin
Version: 1.4.2.RELEASE
Goal Prefix: spring-boot

This plugin has 6 goals:

spring-boot:build-info
  Description: Generate a build-info.properties file based the content of the
    current MavenProject.

spring-boot:help
  Description: Display help information on spring-boot-maven-plugin.
    Call mvn spring-boot:help -Ddetail=true -Dgoal=
 
   to display
    parameter details.

spring-boot:repackage
  Description: Repackages existing JAR and WAR archives so that they can be
    executed from the command line using java -jar. With layout=NONE can also
    be used simply to package a JAR with nested dependencies (and no main
    class, so not executable).

spring-boot:run
  Description: Run an executable archive application.

spring-boot:start
  Description: Start a spring application. Contrary to the run goal, this
    does not block and allows other goal to operate on the application. This
    goal is typically used in integration test scenario where the application
    is started before a test suite and stopped after.

spring-boot:stop
  Description: Stop a spring application that has been started by the 'start'
    goal. Typically invoked once a test suite has completed.

For more information, run 'mvn help:describe [...] -Ddetail'

 .....

 


Write our main class with a RestController:

package com.logicbig.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class MainClass {
    public static void main (String[] args) {
        SpringApplication.run(MainClass.class, args);
    }

    @RestController
    private static class TheController {

        @RequestMapping("/")
        public String handle () {
            return "message from rest handler";
        }
    }
}


Running the exploded application

mvn spring-boot:run will compile and run the exploded application from target directory.


D:\boot-mvn-plugin-example>mvn spring-boot:run
[INFO] Scanning for projects...

  ...............
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.2.RELEASE)

2016-12-08 21:34:02.669  INFO 12376 --- [           main] com.logicbig.example.MainClass           : Starting MainClass on JoeMsi with PID 12376 (D:\boot-mvn-plugin-example\target\classes started by Joe in D:\boot-mvn-plugin-example)
2016-12-08 21:34:02.671  INFO 12376 --- [           main] com.logicbig.example.MainClass           : No active profile set, falling back to default profiles: default
2016-12-08 21:34:02.720  INFO 12376 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@51d7c994: startup date [Thu Dec 08 21:34:02 CST 2016]; root of context hierarchy
2016-12-08 21:34:03.919  INFO 12376 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-12-08 21:34:03.930  INFO 12376 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2016-12-08 21:34:03.932  INFO 12376 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2016-12-08 21:34:04.005  INFO 12376 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2016-12-08 21:34:04.006  INFO 12376 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1290 ms
2016-12-08 21:34:04.151  INFO 12376 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2016-12-08 21:34:04.156  INFO 12376 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-12-08 21:34:04.157  INFO 12376 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-12-08 21:34:04.157  INFO 12376 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-12-08 21:34:04.158  INFO 12376 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2016-12-08 21:34:04.393  INFO 12376 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@51d7c994: startup date [Thu Dec 08 21:34:02 CST 2016]; root of context hierarchy
2016-12-08 21:34:04.460  INFO 12376 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public java.lang.String com.logicbig.example.MainClass$TheController.handle()
2016-12-08 21:34:04.463  INFO 12376 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-12-08 21:34:04.464  INFO 12376 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-12-08 21:34:04.486  INFO 12376 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-08 21:34:04.487  INFO 12376 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-08 21:34:04.516  INFO 12376 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-12-08 21:34:04.634  INFO 12376 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2016-12-08 21:34:04.689  INFO 12376 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-12-08 21:34:04.694  INFO 12376 --- [           main] com.logicbig.example.MainClass           : Started MainClass in 2.47 seconds (JVM running for 4.584)

Now we can access our application in the browser:




Packaging our application as executable jar

Maven <packaging> is 'jar' by default.

Running mvn package spring-boot:repackage will create the executable jar.


D:\boot-mvn-plugin-example>mvn package spring-boot:repackage
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building boot-mvn-plugin-example 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ boot-mvn-plugin-example ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\boot-mvn-plugin-example\src\main\resources
[INFO] skip non existing resourceDirectory D:\boot-mvn-plugin-example\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ boot-mvn-plugin-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ boot-mvn-plugin-example ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\boot-mvn-plugin-example\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ boot-mvn-plugin-example ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.18.1:test (default-test) @ boot-mvn-plugin-example ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ boot-mvn-plugin-example ---
[INFO] Building jar: D:\boot-mvn-plugin-example\target\boot-mvn-plugin-example-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:1.4.2.RELEASE:repackage (default) @ boot-mvn-plugin-example ---
[INFO]
[INFO] --- spring-boot-maven-plugin:1.4.2.RELEASE:repackage (default-cli) @ boot-mvn-plugin-example ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.966 s
[INFO] Finished at: 2016-12-08T21:51:49-06:00
[INFO] Final Memory: 18M/309M
[INFO] ------------------------------------------------------------------------

Now we can run the jar as follows, and access the application in the browser as before:


D:\boot-mvn-plugin-example>java -jar target\boot-mvn-plugin-example-1.0-SNAPSHOT.jar
 ........


Note that we can alternatively add the 'repackage' goal in the pom.xml as well:

<project ....>

......
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.4.2.RELEASE</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

In this case, we can just run this command to get an executable jar.

mvn package



Conflict between multiple main classes

Spring boot automatically finds the 'main' class and runs it . If there are more than one main classes then we will have the following errors:

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.4.2.RELEASE:run (default-cli) on project boot-mvn-plugin-example: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:1.4.2.RELEASE:run failed: Unable to find a single main class from the following candidates [com.logicbig.example.MainClass2, com.logicbig.example.MainClass] -> [Help 1]

To avoid that error we have to include mainClass configuration:

<plugin>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-maven-plugin</artifactId>
     <version>1.4.2.RELEASE</version>
     <configuration>
       <mainClass>com.logicbig.example.MainClass</mainClass>
     </configuration>
</plugin>

Or we can just add a place holder for the mainClass:

<plugin>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-maven-plugin</artifactId>
     <version>1.4.2.RELEASE</version>
     <configuration>
       <mainClass>${myMainClass}</mainClass>
</configuration>
</plugin>

and then run as:

mvn spring-boot:run -DmyMainClass=com.logicbig.example.MainClass2




Example Project

Dependencies and Technologies Used :

  • Spring Boot Web Starter 1.4.2.RELEASE: Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container.
    Corresponding Spring version: 4.3.4.RELEASE
  • JDK 1.8
  • Maven 3.3.9

Spring Boot Mvn Plugin Select All Download
  • boot-mvn-plugin-example
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also