Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run Spring-boot's main using IDE

I have a spring-boot application that needs to:

  • Be deployable as a war in a servlet container
  • Be runnable via `mvn spring-boot:run``

I'd also like to be able to run this application in my IDE (Eclipse or IntelliJ IDEA Community) by right clicking on the main and running it.

Here are the interesting parts of my pom.xml (Note that I do not inherit from spring-boot-starter-parent pom):

...         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>         </dependency>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-tomcat</artifactId>             <scope>provided</scope>         </dependency> ...     <build>         <plugins>             <plugin>                 <artifactId>maven-war-plugin</artifactId>                 <version>2.6</version>                 <configuration>                     <failOnMissingWebXml>false</failOnMissingWebXml>                 </configuration>             </plugin>              <plugin>                 <groupId>org.springframework.boot</groupId>                 <artifactId>spring-boot-maven-plugin</artifactId>                 <version>${spring.boot.version}</version>                 <executions>                     <execution>                         <goals>                             <goal>repackage</goal>                         </goals>                     </execution>                 </executions>             </plugin>         </plugins>     </build> 

Here's my SpringBootServletInitializer:

@Configuration @EnableAutoConfiguration @ComponentScan("com.company.theproject") public class Application extends SpringBootServletInitializer {     private static final Logger logger = LoggerFactory.getLogger(Application.class);      @Override     protected SpringApplicationBuilder configure(SpringApplicationBuilder application)     {         return application.sources(Application.class);     }      public static void main(String[] args)     {         SpringApplication.run(Application.class, args);     } } 

When running the main inside an IDE I get the following error:

org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.     at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:183) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]     at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:156) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]     at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE]     ... 12 common frames omitted 

Seems like mvn spring-boot:run does some more magic that does not happen when running the main directly.

Removing the provided scope from the spring-boot-starter-tomcat dependency fixes this issue but causes trouble when the war is run inside a servlet container.

Right now the only "fix" I've found is to run mvn spring-boot:run within IntelliJ IDEA instead of running the main directly. While this is an acceptable workaround, I'd still like to know why this doesn't work and if it can be fixed.

like image 671
GuiSim Avatar asked May 14 '15 12:05

GuiSim


People also ask

What IDE should I use for Spring Boot?

Visual Studio Code is an ideal lightweight development environment for Spring Boot application developers and there are several useful VS Code extensions including: Spring Boot Tools. Spring Initializr.


2 Answers

A workaround that is strongly inspired from https://youtrack.jetbrains.com/issue/IDEA-140041 is to start your main class with the test classpath (which includes the embedded servlet.)

Steps (IntelliJ 16):

  1. Run -> Edit Configurations -> Add new configuration -> Pick Application type.
  2. Set Main class to <your.main.class>
  3. Set Use classpath of module to <*>_test (the test module!)
  4. Ok and Run it!
like image 121
yop83 Avatar answered Oct 02 '22 14:10

yop83


I believe this could be related to https://youtrack.jetbrains.com/issue/IDEA-107048

IntelliJ IDEA is not injecting the provided dependencies into the CLASSPATH and as Andy stated this is why spring is unable to create the embedded servlet container.

They have a feature request since 2005 about this: https://youtrack.jetbrains.com/issue/IDEABKL-99

Workarounds mentioned in the comments includes having a fake module with the necessary libs and using it as classpath, using the -Xbootclasspath JVM argument or using custom maven profiles for running (compiled) vs building (provided).

like image 44
Marc-André Poulin Avatar answered Oct 02 '22 12:10

Marc-André Poulin