Jetty10+Java11添加JSP模块后启动报无JSP支持、类找不到异常
问题根因
两个报错本质是同一个问题:自定义的WebAppClassLoader破坏了Jetty的类加载规则,没有正确将Jetty服务器自身的类交给父类加载器加载。
从错误栈可以明确看到加载链路问题:
- Jetty启动时尝试加载容器级别的类
org.eclipse.jetty.servlet.listener.ELContextCleaner和org.eclipse.jetty.jsp.JettyJspServlet - 加载请求先走到了自定义的
com.quickheal.loader.WebAppClassLoader - 自定义类加载器没有遵循Jetty类加载的优先级规则,优先在Web应用目录下查找这两个类,找不到就直接抛出ClassNotFoundException,没有委派给加载Jetty核心jar的服务器类加载器。
修复步骤
- 修正自定义类加载器的委派逻辑
所有org.eclipse.jetty.*开头的服务器类、Servlet API相关类,必须优先委派给父类加载器(即加载Jetty启动类的加载器)加载,不能尝试在Web应用的WEB-INF/lib、WEB-INF/classes路径下查找。
如果是继承Jetty原生WebAppClassLoader实现自定义加载器,不要在覆写loadClass方法时跳过父类的系统类检查逻辑,至少要保留如下判断逻辑:@Override public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // Jetty服务器自身类、Servlet容器API类直接交给父加载器加载 if (name.startsWith("org.eclipse.jetty.") || name.startsWith("javax.servlet.")) { return getParent().loadClass(name); } // 业务类、Web应用自有依赖再走自定义加载逻辑 return super.loadClass(name, resolve); } - 确认JSP依赖的部署位置
Jetty 10的JSP相关依赖(包括jetty-jsp、对应的Jasper、EL实现jar)必须放在Jetty服务端的lib目录下,不能只放在Web应用的WEB-INF/lib里。如果之前把JSP依赖打包进了war包,先删掉war包内重复的Jetty JSP相关jar,避免类版本冲突。 - 验证修复结果
修正后重启Jetty,日志中不会再出现NO JSP Support for /和ClassNotFoundException: org.eclipse.jetty.servlet.listener.ELContextCleaner提示,JSP功能可正常加载。
注意:Jetty原生的WebAppClassLoader已经实现了Java EE规范要求的类加载优先级(服务器类优先于Web应用类),自定义类加载器如果随意修改默认委派顺序,非常容易出现容器类找不到、类版本冲突的问题。
内容的提问来源于stack exchange,提问作者Rohini Patil
相关产品推荐
相关产品推荐

