Ejecute Spring-boot’s main usando IDE

Tengo una aplicación de arranque de spring que necesita:

  • Ser desplegable como una guerra en un contenedor servlet
  • Ser ejecutable a través de `mvn spring-boot: run“

También me gustaría poder ejecutar esta aplicación en mi IDE (Comunidad IDEA de Eclipse o IntelliJ) haciendo clic derecho en la main y ejecutándola.

Aquí están las partes interesantes de mi pom.xml (Tenga en cuenta que no heredo de spring-boot-starter-parent pom):

 ...  org.springframework.boot spring-boot-starter-web   org.springframework.boot spring-boot-starter-tomcat provided  ...    maven-war-plugin 2.6  false    org.springframework.boot spring-boot-maven-plugin ${spring.boot.version}    repackage       

Aquí está mi 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); } } 

Cuando ejecuto el main dentro de un IDE obtengo el siguiente 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 

Parece que mvn spring-boot:run hace algo más de magia que no ocurre cuando se ejecuta el main directamente.

La eliminación del scope provided de la dependencia spring-boot-starter-tomcat corrige este problema, pero causa problemas cuando se ejecuta la guerra dentro de un contenedor de servlet.

En este momento, el único “arreglo” que he encontrado es ejecutar mvn spring-boot:run dentro de IntelliJ IDEA en lugar de ejecutar el main directamente. Si bien esta es una solución aceptable, me gustaría saber por qué esto no funciona y si puede solucionarse.

Creo que esto podría estar relacionado con https://youtrack.jetbrains.com/issue/IDEA-107048

IntelliJ IDEA no está inyectando las dependencias provided en CLASSPATH y, como Andy afirmó, esta es la razón por la cual spring no puede crear el contenedor de servlets incorporado.

Tienen una solicitud de función desde 2005 sobre esto: https://youtrack.jetbrains.com/issue/IDEABKL-99

Las soluciones mencionadas en los comentarios incluyen tener un módulo falso con las librerías necesarias y usarlo como classpath, utilizando el argumento -Xbootclasspath JVM o usando perfiles maven personalizados para ejecutar ( compiled ) vs construir ( provided ).

Una solución que está fuertemente inspirada en https://youtrack.jetbrains.com/issue/IDEA-140041 es comenzar su clase principal con el classpath de prueba (que incluye el servlet incorporado).

Pasos (IntelliJ 16):

  1. Run -> Edit Configurations -> Add new configuration -> Elegir tipo de Application .
  2. Establezca Main class en
  3. Establecer Use classpath of module en <*>_test (¡el módulo de prueba!)
  4. Ok y Run !

Pude hacer esto funcionar al cambiar el scope de la dependencia spring-boot-starter-tomcat a “comstackr” en la pestaña Estructura del proyecto-> Dependencias. Esto no afecta a pom.xml, pero permite que estas dependencias estén disponibles para la configuración de ejecución de arranque de spring

Haga clic aquí para ver la imagen de dónde cambiar esta configuración en la idea

mvn spring-boot:run incluye las dependencias provided cuando crea el classpath. Parece que IntelliJ IDEA no lo hace. Sin Tomcat en la ruta de clases, Spring Boot no puede crear un contenedor de servlets incrustado que causa la excepción que está viendo. Podría decirse que esto es un error en IntelliJ ya que, si no hay un contenedor para proporcionar la dependencia, entonces realmente debe estar en el classpath.

Es posible que pueda solucionar el problema anulando la ruta de clase predeterminada que usa IntelliJ al ejecutar el método principal para incluir la dependencia spring-boot-starter-tomcat .

Encuentro esta página y uso el perfil de experto para administrar los perfiles.

    PROD   org.springframework.boot spring-boot-starter-tomcat provided     DEV   org.springframework.boot spring-boot-starter-tomcat TEST     

y config la clase principal beforeLanuce , establece el comando

 mvn clean compile -Pdev 

Pude solucionar este problema en Intellij IDEA 2017.2 agregando el libaray provisto (spring-boot-starter-tomcat) a la configuración del proyecto.

Seleccione Archivo -> Estructura del proyecto. Seleccione Bibliotecas y agregue una nueva biblioteca de proyectos (type = From Maven …). Busque spring-boot-starter-tomcat usando el cuadro de diálogo, seleccione la versión correcta y agréguela haciendo clic en OK. La biblioteca se agrega a la lista de bibliotecas externas.

La desventaja es que si se cambia la versión de Spring Boot, deberá recordar eliminar esta biblioteca y agregar la nueva versión.

Usando el perfil y las instrucciones a continuación, puede agregar un perfil a maven que permita el desarrollo en IntelliJ sin cambiar las cosas para otros entornos.

    org.springframework.boot spring-boot-starter-tomcat provided      intellij   org.springframework.boot spring-boot-starter-tomcat compile     

Haga clic en el botón Maven Projects en el lado derecho de IntelliJ, y en Perfiles , seleccione intellij .

Tuve el mismo problema al usar IntelliJ 2018. Mi solución es:

  1. Vaya a Run -> Edit Configurations .

  2. Seleccione Application && elija su proyecto actual.

  3. Marque Include dependencies with "Provided" scope .

  4. OK -> RUN