You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

代码在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>

总结排查顺序

  1. 先配置日志,拿到完整错误信息(这是最快定位问题的方法);
  2. 调整启动代码,适配Tomcat 9的显式连接器/主机配置;
  3. 检查依赖包是否完整,补充缺失的组件;
  4. 验证Servlet规范版本是否匹配。

内容的提问来源于stack exchange,提问作者Benjq

火山引擎 最新活动