You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至Tomcat10后QuartzInitializerServlet无法匹配Servlet类型报错求助

问题根因

Tomcat 10及以上版本实现的是Jakarta EE规范,将原javax.servlet包下的所有Servlet API全量迁移到了jakarta.servlet包下。当前使用的Quartz版本内置的QuartzInitializerServlet仍基于旧的javax.servlet.Servlet接口实现,Apache官方迁移工具仅会替换项目自身源码、配置文件中的包名引用,不会修改第三方依赖Jar包内部的实现逻辑,因此会抛出Servlet类不匹配的错误。

排查思路
  • 核对当前项目引入的Quartz版本:2.3.2及更早版本的Quartz均基于Java EE(javax包)构建,无原生Jakarta EE适配
  • 核对容器Servlet API版本:Tomcat 10自带的Servlet API为Jakarta EE 5.0+版本,类路径下不存在javax.servlet.Servlet接口定义
  • 核对迁移工具执行范围:确认迁移工具未处理第三方依赖的字节码,旧版Quartz依赖中的Servlet类未完成包名转换
可行解决方案

方案1:升级Quartz到Jakarta适配版本(推荐)

Quartz从2.4.0版本开始官方提供Jakarta EE适配包,类名、配置逻辑和旧版本完全兼容,无需修改web.xml中的配置项,仅需要替换依赖即可。
以Maven依赖为例,将原有Quartz依赖替换为带jakarta分类器的版本:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.4.0</version>
    <classifier>jakarta</classifier>
</dependency>

替换完成后重启容器即可正常加载Quartz初始化Servlet。

方案2:自定义Quartz初始化Servlet

如果受项目其他依赖限制无法升级Quartz版本,可以废弃Quartz自带的初始化Servlet,自行实现基于Jakarta Servlet API的初始化逻辑:

  1. 新建自定义Servlet类,手动完成Quartz调度器的初始化、启动、销毁逻辑,兼容原有web.xml中配置的初始化参数:
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;

public class CustomQuartzInitializer extends HttpServlet {
    private Scheduler scheduler;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        String startOnLoad = config.getInitParameter("start-scheduler-on-load");
        try {
            scheduler = StdSchedulerFactory.getDefaultScheduler();
            if ("true".equalsIgnoreCase(startOnLoad)) {
                scheduler.start();
            }
            config.getServletContext().setAttribute(Scheduler.class.getName(), scheduler);
        } catch (SchedulerException e) {
            throw new ServletException("Quartz调度器初始化失败", e);
        }
    }

    @Override
    public void destroy() {
        String shutdownOnUnload = getInitParameter("shutdown-on-unload");
        if ("true".equalsIgnoreCase(shutdownOnUnload) && scheduler != null) {
            try {
                scheduler.shutdown();
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. 修改web.xml中Quartz初始化Servlet的servlet-class配置为上述自定义类的全限定名,其余init-param、load-on-startup配置保持不变即可。

方案3:降级Tomcat版本

如果暂时没有改造计划,可以将Tomcat降级到9.x版本,Tomcat 9是最后一个基于Java EE(javax包)规范的Tomcat稳定版本,和旧版Quartz原生兼容,不需要修改任何代码或依赖。

注意:不要尝试在Tomcat 10中手动引入javax.servlet-api依赖,会和容器自带的Jakarta Servlet API产生类加载冲突,引发更多不可预期的运行错误。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:18:24