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 1.4.2.RELEASE
Corresponding Spring Version 4.3.4.RELEASE - Spring Boot Web Starter : Starter for building web, including RESTful, applications using Spring
MVC. Uses Tomcat as the default embedded container.
- JDK 1.8
- Maven 3.3.9
|