Jetty启动页面加载失败 每次访问URL均触发空指针异常
解决Jetty 9.4.18.v20190429的空指针异常问题
我之前维护Jetty服务时碰到过几乎一模一样的问题,结合你给出的异常栈信息,咱们一步步定位和解决:
异常根源分析
从栈信息看,空指针出现在org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1602),对应Jetty 9.4.18的源码,这一行是调用过滤链中某个Filter的doFilter方法,但该Filter实例为null——大概率是Filter初始化失败却被错误加入过滤链,或是自定义Filter逻辑存在空引用,也可能是Jetty本身的版本bug导致。
排查与解决方案
1. 检查Filter的初始化状态
- 先查看Jetty启动日志,有没有
Failed to initialize filter这类初始化失败的报错,NPE往往是初始化失败的后续表现,根源在启动阶段的异常。 - 临时移除所有自定义Filter(包括web.xml配置的和注解方式的),重启Jetty后访问任意URL,如果NPE消失,说明问题出在某个自定义Filter上。
- 逐个恢复Filter,定位出问题的那个,重点检查它的
init方法:确保没有未捕获的异常,不要在init里依赖还未初始化的服务(比如提前调用了null的Bean)。举个规范示例:
public class CustomFilter implements Filter { @Override public void init(FilterConfig config) throws ServletException { try { // 初始化逻辑要做null校验和异常捕获 String param = config.getInitParameter("key"); if (param == null) { throw new ServletException("Missing required init parameter 'key'"); } // 其他初始化操作 } catch (Exception e) { // 包装异常抛出,让Jetty明确感知初始化失败 throw new ServletException("CustomFilter initialization failed", e); } } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 先校验核心参数非空 if (request == null || response == null || chain == null) { throw new ServletException("Invalid filter parameters"); } // 业务逻辑 chain.doFilter(request, response); } // 其他方法... }
2. 排查依赖冲突
Jetty 9.4.x依赖Servlet 3.1规范,如果项目中引入了更高版本(比如Servlet 4.0)或更低版本的javax.servlet-api jar,会导致类加载冲突,进而引发奇怪的空指针。
- 检查项目依赖(比如Maven的
pom.xml或Gradle的build.gradle),确保Servlet API的scope设为provided(由Jetty提供),避免打包进项目:
<!-- Maven示例 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
- 清理项目依赖缓存(比如执行
mvn clean install -U),确保没有冲突的jar包残留。
3. 升级Jetty版本
Jetty 9.4.18确实存在一些过滤链相关的已知小bug,后续版本已经修复。建议升级到9.4系列的稳定版本,比如9.4.51.v20230217(这是9.4系列的最后一个稳定版),升级后大概率能解决这类版本导致的空指针问题。
内容的提问来源于stack exchange,提问作者Bhavesh Modi
相关产品推荐
相关产品推荐

