代码在Embedded Apache Tomcat 8正常运行,Tomcat 9异常,原因何在?
解决Tomcat 9.0.5 Embedded无法启动的问题
Hey Benjq, 我碰到过不少开发者从Tomcat 8 Embedded迁移到9时踩这个坑,大概率是Tomcat 9对嵌入式API的兼容性调整导致的——咱们一步步排查解决:
1. 先搞定日志,拿到完整错误信息
你提到控制台输出不完整,这是定位问题的最大阻碍。Tomcat 9默认日志级别更高,很多关键错误被过滤了。手动设置日志配置,就能看到启动时的真实问题:
操作步骤:
- 在项目根目录创建
logging.properties文件,内容如下:
handlers = java.util.logging.ConsoleHandler .level = INFO java.util.logging.ConsoleHandler.level = FINE java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
- 在启动类的最开头添加日志配置加载代码:
System.setProperty("java.util.logging.config.file", "logging.properties");
重新启动后,控制台会输出更详细的日志,比如类缺失、初始化失败等具体信息,这是快速定位问题的核心。
2. 适配Tomcat 9的嵌入式API变化
Tomcat 9对嵌入式启动的核心逻辑做了不少调整,最常见的是连接器和主机配置的隐性要求。对比Tomcat 8和9的启动代码:
Tomcat 8 可行的代码:
Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); tomcat.addWebapp("/", new File("webapp").getAbsolutePath()); tomcat.start(); tomcat.getServer().await();
Tomcat 9 需要调整的代码:
Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); // 显式创建并绑定HTTP连接器(Tomcat 9推荐显式配置) Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setPort(8080); tomcat.getService().addConnector(connector); // 显式配置默认主机(避免Tomcat 9的自动配置逻辑问题) Host host = tomcat.getHost(); host.setAppBase("."); // 将Web应用绑定到指定主机 tomcat.addWebapp(host, "/", new File("webapp").getAbsolutePath()); tomcat.start(); tomcat.getServer().await();
3. 检查依赖包的完整性
Tomcat 9 Embedded的依赖拆分比8更细,之前只引入tomcat-embed-core可能不够,需要补充日志和JSP相关依赖(如果用到的话):
Maven 依赖示例:
<dependencies> <!-- 核心嵌入式Tomcat依赖 --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>9.0.5</version> </dependency> <!-- 日志依赖,否则启动时可能无日志或隐性失败 --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-logging-juli</artifactId> <version>9.0.5</version> </dependency> <!-- 如果Web应用包含JSP,必须添加这个依赖 --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>9.0.5</version> </dependency> </dependencies>
4. 验证Servlet规范兼容性
Tomcat 9支持Servlet 4.0规范,如果你Web应用的web.xml还是用的旧版本(比如3.0),虽然理论上兼容,但可能触发隐性问题。建议更新web.xml的根元素:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 你的Web应用配置 --> </web-app>
总结排查顺序
- 先配置日志,拿到完整错误信息(这是最快定位问题的方法);
- 调整启动代码,适配Tomcat 9的显式连接器/主机配置;
- 检查依赖包是否完整,补充缺失的组件;
- 验证Servlet规范版本是否匹配。
内容的提问来源于stack exchange,提问作者Benjq




