web-dev-qa-db-fra.com

Exécutez la commande principale de Spring-boot en utilisant IDE

J'ai une application Spring-Boot qui doit:

  • Être déployable comme une guerre dans un conteneur de servlets
  • Être exécutable via `mvn spring-boot: run``

J'aimerais également pouvoir exécuter cette application dans ma communauté IDE (Eclipse ou IntelliJ IDEA] en cliquant avec le bouton droit de la souris sur la variable main et en l'exécutant.

Voici les parties intéressantes de mon fichier pom.xml (notez que je n'hérite pas du pom spring-boot-starter-parent):

...
        <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>

Voici ma 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);
    }
}

Lorsque j'exécute le principal dans un IDE, l'erreur suivante apparaît:

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

On dirait que mvn spring-boot:run fait encore plus de magie qui ne se produit pas lorsque vous exécutez directement la main.

La suppression de l'étendue provided de la dépendance spring-boot-starter-Tomcat résout ce problème, mais provoque des problèmes lorsque la guerre est exécutée à l'intérieur d'un conteneur de servlet.

À l'heure actuelle, le seul «correctif» que j'ai trouvé consiste à exécuter mvn spring-boot:run dans IntelliJ IDEA au lieu d'exécuter directement le principal. Bien que cette solution de contournement soit acceptable, j'aimerais tout de même savoir pourquoi cela ne fonctionne pas et si cela peut être corrigé.

30
GuiSim

Je pense que cela pourrait être lié à https://youtrack.jetbrains.com/issue/IDEA-107048

IntelliJ IDEA n'injecte pas les dépendances provided dans le CLASSPATH et, comme Andy l'a déclaré, c'est pourquoi spring ne peut pas créer le conteneur de servlets intégré.

Ils ont une demande de fonctionnalité depuis 2005 à ce sujet: https://youtrack.jetbrains.com/issue/IDEABKL-99

Les solutions mentionnées dans les commentaires incluent l'utilisation d'un faux module avec les bibliothèques nécessaires et son utilisation comme chemin de classe, l'utilisation de l'argument JVM -Xbootclasspath ou l'utilisation de profils Maven personnalisés pour exécuter (compiled) vs building (provided). 

14

Une solution de contournement fortement inspirée de https://youtrack.jetbrains.com/issue/IDEA-140041 consiste à démarrer votre classe principale avec le classpath de test (qui inclut le servlet intégré.)

Étapes (IntelliJ 16):

  1. Run -> Edit Configurations -> Add new configuration -> Choisissez le type Application.
  2. Définissez Main class sur <your.main.class>
  3. Définissez Use classpath of module sur <*>_test (le module de test!)
  4. Ok et Run it!
23
yop83

J'ai réussi à faire fonctionner cela en modifiant la portée de la dépendance Spring-boot-starter-Tomcat en "compiler" sous l'onglet Structure du projet-> Dépendances. Cela n'affecte pas pom.xml mais permet à ces dépendances d'être disponibles pour la configuration de démarrage à ressort

Cliquez ici pour une image sur où changer ce réglage d’idée

6
nishantkyal

mvn spring-boot:run inclut les dépendances provided lorsqu’il crée le chemin de classe. Il semble qu'IntelliJ IDEA ne le soit pas. Sans Tomcat sur le chemin de classe, Spring Boot ne peut pas créer de conteneur de servlet intégré, ce qui provoque l'exception que vous voyez. On peut soutenir que c'est un bogue dans IntelliJ car, s'il n'y a pas de conteneur pour fournir la dépendance, alors il faut vraiment qu'il soit sur le chemin de classe.

Vous pourrez peut-être résoudre le problème en remplaçant le chemin d'accès aux classes par défaut utilisé par IntelliJ lors de l'exécution de la méthode main pour inclure la dépendance spring-boot-starter-Tomcat.

3
Andy Wilkinson

J'ai pu contourner ce problème dans Intellij IDEA 2017.2 en ajoutant le libaray fourni (spring-boot-starter-Tomcat) à la configuration du projet.

Sélectionnez Fichier -> Structure du projet. Sélectionnez Bibliothèques et ajoutez une nouvelle bibliothèque de projet (type = De Maven ...). Recherchez Spring-Boot-Starter-Tomcat dans la boîte de dialogue, sélectionnez la version appropriée et ajoutez-la en cliquant sur OK. La bibliothèque est ajoutée à la liste des bibliothèques externes.

L'inconvénient est que si la version de Spring Spring est modifiée, vous devez vous rappeler de supprimer cette bibliothèque et d'ajouter la nouvelle version.

1
phn

En utilisant le profil et les instructions ci-dessous, vous pouvez ajouter un profil à maven qui permet le développement dans IntelliJ sans changer les choses pour d’autres environnements.

<!-- Leave original dependency as-is -->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-Tomcat</artifactId>
            <scope>provided</scope>
    </dependency>
</dependencies>

<profiles>
    <!-- Enable this profile to run in IntelliJ. IntelliJ excludes provided dependencies from compile by default. -->
    <profile>
        <id>intellij</id>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-Tomcat</artifactId>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    </profile>
</profiles>

Cliquez sur le bouton Projets Maven situé à droite d’IntelliJ, puis sous Profils , sélectionnez intellij.

1
AnthonyW

Je trouve cette page et utilise le profil maven pour gérer les profils. 

    <profiles>
              <profile>
                   <id>PROD</id>
                   <dependencies>
                        <dependency>
                             <groupId>org.springframework.boot</groupId>
                             <artifactId>spring-boot-starter-Tomcat</artifactId>
                             <scope>provided</scope>
                        </dependency>
                   </dependencies>
              </profile>
<profile>
                   <id>DEV</id>
                   <dependencies>
                        <dependency>
                             <groupId>org.springframework.boot</groupId>
                             <artifactId>spring-boot-starter-Tomcat</artifactId>
                             <scope>TEST</scope>
                        </dependency>
                   </dependencies>
              </profile>
         </profiles>

et configurez la classe principale beforeLanuce, définissez la commande 

mvn clean compile -Pdev
1
wang xinli

Suivez ces étapes:

  1. En haut à droite de la fenêtre intellij, cliquez sur le menu déroulant, sélectionnez Modifier la configuration pour ouvrir une nouvelle fenêtre.

  2. Dans cette fenêtre, en haut à gauche, cliquez sur le bouton "+" et sélectionnez le démarrage du sprint.

 enter image description here

  1. Ajoutez ensuite votre classe principale et d’autres détails, comme indiqué dans la capture d’écran .  enter image description here

  2. Maintenant, lancez l'application.

0
KayV

J'ai eu le même problème avec IntelliJ 2018. Ma solution est la suivante:

  1. Allez à Run -> Edit Configurations.

  2. Sélectionnez Application && choisissez votre projet actuel.

  3. Vérifiez Include dependencies with "Provided" scope.

  4. OK -> RUN 

0
Sparow199