如何解决Tomcat 9启动时出现Mojarra错误的问题
将Tomcat6环境下的应用迁移到Tomcat9后,启动时出现监听器启动失败导致上下文初始化失败的问题,具体启动日志如下:
30-Dec-2022 15:22:16.039 INFO [main] com.sun.faces.config.ConfigureListener.contextInitialized 为上下文'/ordini'初始化Mojarra (1.2_12-b01-FCS) SEVERE [main] org.apache.catalina.core.StandardContext.startInternal 一个或多个监听器启动失败。详细信息请查看对应的容器日志文件 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal 上下文[/ordini]因之前的错误启动失败 30-Dec-2022 15:22:17.679 INFO [main] org.apache.catalina.startup.HostConfig.deployDescriptor 部署描述符[C:\smiweb\tomcat-9.0.70\conf\Catalina\localhost\ordini.xml]的部署已完成,耗时[5,828]毫秒 30-Dec-2022 15:22:17.679 INFO [main] org.apache.catalina.startup.HostConfig.deployDescriptor 正在部署部署描述符[C:\smiweb\tomcat-9.0.70\conf\Catalina\localhost\ROOT.xml] 30-Dec-2022 15:22:17.679 WARNING [main] org.apache.catalina.startup.HostConfig.deployDescriptor 部署描述符[C:\smiweb\tomcat-9.0.70\conf\Catalina\localhost\ROOT.xml]中的path属性值[]已被忽略 30-Dec-2022 15:22:17.679 WARNING [main] org.apache.catalina.startup.HostConfig.deployDescriptor 使用外部docBase部署描述符[C:\smiweb\tomcat-9.0.70\conf\Catalina\localhost\ROOT.xml]意味着appBase中的目录[C:\smiweb\tomcat-9.0.70\webapps\ROOT]将被忽略 30-Dec-2022 15:22:20.711 WARNING [main] org.apache.catalina.startup.ContextConfig.validateSecurityRoles 在<auth-constraint>中使用的安全角色名称[smi]未在<security-role>中定义 30-Dec-2022 15:22:20.929 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描TLD但未包含任何TLD。启用此日志记录器的调试日志可获取所有被扫描但未找到TLD的JAR完整列表。扫描期间跳过不需要的JAR可提高启动时间和JSP编译时间。 30-Dec-2022 15:22:20.992 INFO [main] com.sun.faces.config.ConfigureListener.contextInitialized 为上下文''初始化Mojarra (1.2_12-b01-FCS) 30-Dec-2022 15:22:20.992 WARNING [main] com.sun.faces.config.ConfigureListener.contextInitialized JSF1059: 警告!com.sun.faces.verifyObjects特性用于帮助不使用工具的开发者。如果使用IDE或应用部署到生产环境,不应启用此特性,因为它会影响应用启动时间。 30-Dec-2022 15:22:21.586 INFO [main] com.sun.faces.spi.InjectionProviderFactory.createInstance JSF1048: 存在PostConstruct/PreDestroy注解。标记了这些注解的ManagedBeans方法将被处理。 30-Dec-2022 15:22:22.148 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal 一个或多个监听器启动失败。详细信息请查看对应的容器日志文件
排查及解决步骤:
查看详细错误日志:主日志仅提示监听器启动失败,需查看Tomcat的
localhost.log或localhost.*.log文件(位于tomcat-9.0.70/logs目录下),获取监听器启动失败的具体异常信息(如类找不到、依赖缺失、类版本冲突等)。修复安全角色定义问题:根据日志中的警告,安全角色
smi在<auth-constraint>中被使用但未在<security-role>中定义,需在应用的web.xml中添加如下配置:<security-role> <role-name>smi</role-name> </security-role>关闭JSF的verifyObjects特性:日志提示
com.sun.faces.verifyObjects特性影响启动时间,建议在web.xml中关闭该特性:<context-param> <param-name>com.sun.faces.verifyObjects</param-name> <param-value>false</param-value> </context-param>解决JSF版本兼容性问题:当前使用的Mojarra 1.2是JSF 1.2版本,而Tomcat9基于Servlet 4.0规范,JSF 1.2与Servlet 4.0存在兼容性差异。建议:
- 移除应用
WEB-INF/lib中旧的JSF相关JAR(如jsf-api.jar、jsf-impl.jar),改用与Servlet 4.0兼容的JSF版本(如Mojarra 2.3)。 - 若无法升级JSF,需确保应用中所有依赖的Servlet API版本与Tomcat9兼容,移除应用中打包的
servlet-api.jar、jsp-api.jar等(Tomcat9已自带这些API)。
- 移除应用
检查JAR冲突:排查应用
WEB-INF/lib与Tomcat9lib目录中的JAR是否存在版本冲突,比如EL表达式相关JAR、JSP相关JAR,移除重复或版本不兼容的JAR文件。检查自定义监听器:若应用中存在自定义的Servlet监听器(如实现
ServletContextListener的类),需验证其是否兼容Servlet 4.0规范,修复监听器代码中的兼容性问题(如方法签名变化、依赖类版本问题)。
内容的提问来源于stack exchange,提问作者Massimo Tonini

