遇到Unable to start embedded Tomcat或者自动停止如何查看具体报错信息

  • 本篇可以说是是上篇spring boot项目打印banner后停止的具体操作
  • 遇到org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat问题原因很多,网上说的一般情况不一样。
  • 所谓“授人以鱼不如授人以渔”,本篇要给大家带来的就是自己如何debug程序去找症结所在。
  • 首先找到spring boot创建web服务的地方ServletWebServerApplicationContext#onRefresh方法(当然这是web应用所以是这个类)
protected void onRefresh() {
		super.onRefresh();
		try {
    		 // 很明显就是这个方法
			createWebServer();
		}
		catch (Throwable ex) {
			throw new ApplicationContextException("Unable to start web server", ex);
		}
	}
private void createWebServer() {
		WebServer webServer = this.webServer;
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
			ServletWebServerFactory factory = getWebServerFactory();
			// 重点进入getWebServer方法
			this.webServer = factory.getWebServer(getSelfInitializer());
		}
		else if (servletContext != null) {
			try {
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
				throw new ApplicationContextException("Cannot initialize servlet context",
						ex);
			}
		}
		initPropertySources();
	}
  • 再进入TomcatServletWebServerFactory#getWebServer->getTomcatWebServer->TomcatWebServer#TomcatWebServer(Tomcat tomcat, boolean autoStart)TomcatWebServer的构造方法->initialize
	private void initialize() throws WebServerException {
		TomcatWebServer.logger
				.info("Tomcat initialized with port(s): " + getPortsDescription(false));
		synchronized (this.monitor) {
			try {
				addInstanceIdToEngineName();

				Context context = findContext();
				context.addLifecycleListener((event) -> {
					if (context.equals(event.getSource())
							&& Lifecycle.START_EVENT.equals(event.getType())) {
						// Remove service connectors so that protocol binding doesn't
						// happen when the service is started.
						removeServiceConnectors();
					}
				});

				// Start the server to trigger initialization listeners
				this.tomcat.start();

				// We can re-throw failure exception directly in the main thread
				// 重点是这个,按照我的理解这个方法会收集启动时的异常并抛出
				rethrowDeferredStartupExceptions();

				try {
					ContextBindings.bindClassLoader(context, context.getNamingToken(),
							getClass().getClassLoader());
				}
				catch (NamingException ex) {
					// Naming is not enabled. Continue
				}

				// Unlike Jetty, all Tomcat threads are daemon threads. We create a
				// blocking non-daemon to stop immediate shutdown
				startDaemonAwaitThread();
			}
			catch (Exception ex) {
				stopSilently();
				throw new WebServerException("Unable to start embedded Tomcat", ex);
			}
		}
	}
  • TomcatWebServer#rethrowDeferredStartupExceptions 重点是这个,按照我的理解这个方法会收集启动时的异常并抛出。
  • 我在这里debug下就明了了,具体异常就有了。
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
  • 第一个阻塞点的异常我处理完了,遇到第二个问题依然是自动停止的情况,于是我又在AbstractApplicationContext#refresh打断点,看具体是什么异常
    在这里插入图片描述
  • 最后一个问题我发现居然还没有选择环境,只读取到默认的default,该断点在ConfigFileApplicationListener#load方法;目前看到该类是一个EnvironmentPostProcessor,主要功能就把它看成是处理处理文件的吧(环境事件的后处理器,不知道对不对,如果不对的话,请在评论下方指正,感谢您)
    在这里插入图片描述
  • 在外层debug的时候看到的确只读了application.properties配置文件,该断点位置在SpringApplication#run方法
    在这里插入图片描述
  • 于是我在application.properties(猜想他们可能是-D参数启动的吧)文件加入 spring.profiles.active=dev终于可以启动了。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 主要根据错误信息把错误一一解决了改改配置就能启动了
  • 本人水平有限,如果文章有误的地方,希望批评指正,感谢您的观看。

posted on   愤怒的苹果ext  阅读(2823)  评论(1编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示