Caused by: : Unable to start ServletWebServer

时间:2025-01-19 07:47:59
: Unable to start web server; nested exception is : Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
	at (:156)
	at (:544)
	at (:141)
	at (:747)
	at (:397)
	at (:315)
	at (:1226)
	at (:1215)
	at (:11)
Caused by: : Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
	at (:203)
	at (:179)
	at (:153)
	... 8 common frames omitted

新加了个包,编译正常,启动出现错误,所以问题一定在我新加的包里(此处的包省略,假设为jj-xx),这个包里的jj-xx依赖有

[INFO]       +- :-api:jar:4.0.1:compile
[INFO]       +- :jsp-api:jar:2.2:compile
[INFO]       +- :jetty-server:jar:9.4.20.v20190813:compile
[INFO]       |  +- :jetty-http:jar:9.4.20.v20190813:compile
[INFO]       |  |  \- :jetty-util:jar:9.4.20.v20190813:compile
[INFO]       |  \- :jetty-io:jar:9.4.20.v20190813:compile
[INFO]       +- :groovy-all:jar:2.4.13:compile
[INFO]       +- :commons-exec:jar:1.3:compile
[INFO]       \- cglib:cglib:jar:2.1:compile
[INFO]          +- asm:asm:jar:1.5.3:compile
[INFO]          +- asm:asm-util:jar:1.3.4:compile
[INFO]          \- aspectwerkz:aspectwerkz-core:jar:0.8.1:compile

另外因为一些上下文需要,之前还引入了spring-web相关的依赖(这里猜想可能是因为一些包的必要条件满足才导致程序启动为web程序

	<dependency>
            <groupId></groupId>
            <artifactId>spring-web</artifactId>
            <version>xxx</version>
        </dependency>

如下是解决方式

根据报错提示,application启动的时候,根据webApplicationType判断的运行环境

 protected ConfigurableApplicationContext createApplicationContext() {
       Class<?> contextClass = ;
       if (contextClass == null) {
           try {
               switch() {
               case SERVLET:
                   contextClass = ("");

继续往下看,webApplicationType是deduceFromClasspath生成的

         = ();

最后是deduceFromClasspath方法里,返回servlet方法的逻辑,大概有三种情况

  • 存在 && 不存在 && 不存在,为REACTIVE程序
  • SERVLET_INDICATOR_CLASSES字符串数组里有一个不存在时,为非web程序
  • SERVLET_INDICATOR_CLASSES都存在时,为SERVLET环境
    注: String[] SERVLET_INDICATOR_CLASSES = new String[]{"", ""};
static WebApplicationType deduceFromClasspath() {
        if (("", (ClassLoader)null) && !("", (ClassLoader)null) && !("", (ClassLoader)null)) {
            return REACTIVE;
        } else {
            String[] var0 = SERVLET_INDICATOR_CLASSES;
            int var1 = ;

            for(int var2 = 0; var2 < var1; ++var2) {
                String className = var0[var2];
                if (!(className, (ClassLoader)null)) {
                    return NONE;
                }
            }

            return SERVLET;
        }
    }

综上所述,只存在spring-web时还是非web程序,当我引入依赖并引入其他有关 时,就导致我的运行程序为SERVLET。

另外还提供另一种解决方式
外层配置里加上,这是创建 Environment
根据准备阶段的推断 Web 应用类型创建对应的 ConfigurableEnvironment 实例:

-application-type=none
#-application-type=servlet

private ConfigurableEnvironment getOrCreateEnvironment() {
        if ( != null) {
            return ;//这里就是根据外层配置去获取的none类型
        } else {
            switch() {
            case SERVLET:
                return new StandardServletEnvironment();
            case REACTIVE:
                return new StandardReactiveWebEnvironment();
            default:
                return new StandardEnvironment();
            }
        }
    }
    ```