使用 IDE 运行 Spring-boot 的 main

Posted

技术标签:

【中文标题】使用 IDE 运行 Spring-boot 的 main【英文标题】:Run Spring-boot's main using IDE 【发布时间】:2015-07-26 02:17:05 【问题描述】:

我有一个 spring-boot 应用程序需要:

可部署为 servlet 容器中的战争 可以通过 `mvn spring-boot:run` 运行

我还希望能够在我的 IDE(Eclipse 或 IntelliJ IDEA 社区)中通过右键单击 main 并运行它来运行此应用程序。

这是我的 pom.xml 中有趣的部分(请注意,我不是从 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>

这是我的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);
    

在 IDE 中运行 main 时出现以下错误:

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

似乎mvn spring-boot:run 具有更多直接运行main 时不会发生的魔力。

spring-boot-starter-tomcat 依赖项中删除 provided 范围可解决此问题,但在 servlet 容器内运行战争时会导致问题。

现在我发现的唯一“修复”是在 IntelliJ IDEA 中运行 mvn spring-boot:run,而不是直接运行 main。虽然这是一个可以接受的解决方法,但我仍然想知道为什么这不起作用以及是否可以修复。

【问题讨论】:

另外提一下:运行mvn spring-boot:run不会触发调试器(当点击调试图标时,它仍然使用相同的mvn命令,因此启动应用程序的方式与点击运行图标相同) 我要补充一点,让 spring-boot-starter-tomcat 成为编译/运行时依赖项(而不是提供)可能会造成麻烦。这取决于容器的配置方式。如果涉及安全管理器,它可能会忽略您的库副本......或者它可能会因为您试图覆盖它而排除在外......或者它可能会使用您的并且没问题。 【参考方案1】:

我在使用 IntelliJ 2018 时遇到了同样的问题。 最初,请确保您已在 IntelliJ 中添加了 spring 项目的 maven 库。

我的解决办法是:

    转到Run -> Edit Configurations

    选择Application && 选择您当前的项目。

    检查Include dependencies with "Provided" scope

    OK -> RUN

【讨论】:

谢谢;这样可以节省时间!【参考方案2】:

按照以下步骤操作:

    在intellij窗口右上角,点击下拉菜单,选择编辑配置,会打开一个新窗口。

    在此窗口的左上角,单击“+”按钮并选择 sprint boot。

    然后添加主类和其他详细信息,如屏幕截图所示。

    现在运行应用程序。

【讨论】:

这仅在 IDEA Ultimate 中可用(OP 确实要求 Eclipse 或 IDEA Community)。【参考方案3】:

我能够通过在项目结构->依赖项选项卡下将 spring-boot-starter-tomcat 依赖项的范围更改为“编译”来完成这项工作。这不会影响 pom.xml,但允许此依赖项可用于 spring boot 运行配置

Click here for image on where to change this setting in idea

【讨论】:

我无法在 Intellij IDEA 2017.2 中使用此解决方案 @phn:这适用于我 2017.2,我必须设置 spring-boot-starter-tomcat、tomcat-embed-core、tomcat-embed-el 和 tomcat-embed-websocket 编译为描述的。尝试搜索其他“提供的”依赖项,这些依赖项也可能丢失,但它们是 spring-boot-starter-tomcat 的依赖项。【参考方案4】:

使用下面的配置文件和说明,您可以向 maven 添加配置文件,允许在 IntelliJ 中进行开发,而无需针对其他环境进行更改。

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

点击IntelliJ右侧的Maven Projects按钮,在Profiles下选择intellij

【讨论】:

【参考方案5】:

通过将提供的 libaray (spring-boot-starter-tomcat) 添加到项目配置中,我能够在 Intellij IDEA 2017.2 中解决此问题。

选择文件 -> 项目结构。选择 Libraries 并添加一个新的项目库(类型 = From Maven...)。使用对话框搜索 spring-boot-starter-tomcat,选择正确的版本并单击 OK 添加它。该库被添加到外部库列表中。

缺点是,如果 Spring Boot 版本发生变化,你必须记得删除这个库并添加新版本。

【讨论】:

【参考方案6】:

我找到了这个page,并使用 maven 配置文件来管理配置文件。

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

并配置主类beforeLanuce,设置命令

mvn clean compile -Pdev

【讨论】:

这也适用于 Intellij maven 插件 -> 在右侧检查“配置文件”【参考方案7】:

一个从https://youtrack.jetbrains.com/issue/IDEA-140041 强烈启发的解决方法是使用测试类路径(包括嵌入式 servlet)启动您的主类。

步骤(IntelliJ 16):

    Run -> Edit Configurations -> Add new configuration -> 选择 Application 类型。 将Main class 设置为&lt;your.main.class&gt;Use classpath of module 设置为&lt;*&gt;_test(测试模块!) OkRun 它!

【讨论】:

我没有 _test 模块。 yop83 或@Thirdman 能否分享一下您是如何获得该测试模块的?【参考方案8】:

我相信这可能与https://youtrack.jetbrains.com/issue/IDEA-107048有关

IntelliJ IDEA 没有将 provided 依赖项注入到 CLASSPATH 中,正如 Andy 所说,这就是 spring 无法创建嵌入式 servlet 容器的原因。

自 2005 年以来,他们有一个关于此的功能请求:https://youtrack.jetbrains.com/issue/IDEABKL-99

cmets 中提到的解决方法包括使用带有必要库的假模块并将其用作类路径,使用 -Xbootclasspath JVM 参数或使用自定义 maven 配置文件来运行 (compiled) 与构建 (provided)。

【讨论】:

请您介意扩展一下如何在 IntelliJ 中实施解决方案?请问最简单的方法是什么? @John,我根据上述解决方法编写了一个解决方案。见下文。 看起来 Intellij IDEA 2018.1 修复了这个问题。 > 在“运行/调试配置”对话框中,为应用程序和 Spring Boot 配置提供了一个新的包含“已提供”范围选项的依赖项。这个新功能允许您在需要时将“提供的”依赖项添加到类路径中。请注意,Spring Boot 应用程序默认启用包含具有“已提供”范围的依赖项选项。 blog.jetbrains.com/idea/2018/02/…【参考方案9】:

mvn spring-boot:run 在创建类路径时包含provided 依赖项。听起来 IntelliJ IDEA 没有。如果类路径上没有 Tomcat,Spring Boot 无法创建嵌入式 servlet 容器,这会导致您看到的异常。可以说这是 IntelliJ 中的一个错误,因为如果没有容器来提供依赖项,那么它确实需要在类路径上。

您可以通过覆盖 IntelliJ 在运行 main 方法以包含 spring-boot-starter-tomcat 依赖项时使用的默认类路径来解决此问题。

【讨论】:

以上是关于使用 IDE 运行 Spring-boot 的 main的主要内容,如果未能解决你的问题,请参考以下文章

无法在 IntelliJ Idea 中启动 spring-boot 应用程序

IntelliJ IDEA 2017版 spring-boot2.0.访问jsp页面;IDE Springboot JSp 页面访问

使用Spring-Boot快速搭建一个后台服务器

spring-boot:apache commons-configuration2 异常:java.lang.IllegalArgumentException: name原因分析

spring-boot入门

Spring-Boot:同时处理多个请求