java - 创建 log4j2 记录器会导致在启动 Tomcat webapp 时检索 JNDI 命名上下文失败
问题描述
我有一个 Java 7 webapp 我正在尝试在运行 Tomcat 7.0.53 的服务器上工作。在尝试使用 Log4j 之前,我的 webapp 已经能够毫无问题地启动和运行。
现在,我正在尝试在我的应用程序中添加和使用 Log4j2。通过注释掉创建 Log4j Logger 的代码行,我发现当 Tomcat 尝试启动我的 webapp 时,它会导致我的 webapp 失败。以下是来自的具体错误catalina.out
:
Oct 22, 2018 4:28:37 PM org.apache.catalina.deploy.NamingResources cleanUp
WARNING: Failed to retrieve JNDI naming context for container [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/db-status-checker]] so no cleanup was performed for that container
javax.naming.NamingException: No naming context bound to this class loader
NamingException 发生是因为查找java:comp/env
失败。
这是导致上述警告和后续异常的特定代码行:
static Logger log = LogManager.getLogger(
DBTest.class.getName()
);
我使用的 IDE 是 Intellij IDEA。
如果您需要更多信息,请告诉我。谢谢你。
解决方案
如果您需要更多信息,请告诉我。
在询问有关 Tomcat 的问题时,指定您使用的确切版本(xyz) 很重要。我希望您的 Tomcat 7.0.z 版本不是n岁。
当 Tomcat 尝试启动我的 webapp 时,它导致我的 webapp 失败。
错误消息说它是由方法“org.apache.catalina.deploy.NamingResources cleanUp”记录的。正如您可以从名称中猜到的那样,它不会在启动时发生,而是在关闭时发生。
日志文件和其他日志文件(尤其是 localhost.log)中的其他消息是什么?
我的猜测是其他东西阻止它启动,清理错误只是其后果。
静态 Logger 日志
为什么是“静态”?仅当您有此类的多个实例(并且希望跨实例共享记录器)时,这才有意义。如果只有一个实例(一个Servlet,一个Controller通常作为一个实例存在),使用实例字段更有意义。
一般注意事项:
- 常见故障排除提示。您可以尝试在 NamingResources 类中放置一个断点并查看它是如何启动的。您可以尝试在 StandardContext 类中放置一个断点并查看它是如何启动的。JNDI 在 StandardContext 启动序列的某个步骤初始化。
- 您可以尝试简化 Log4J 的配置。(以确保它不在其配置中使用 JNDI)。
- JNDI 通常是通过创建 InitialContext 并通过它进行查找来访问的。InitialContext 根据在其中运行的 Web 应用程序选择 JNDI 树。这是通过查看当前线程(又名 TCCL)的 Thread.getContextClassLoader() 来完成的。如果 TCCL 错误,JNDI 将无法访问。(NamingResources 类是一个例外,因为它可以访问 Tomcat 内部)。
推荐阅读
- python - 使用 Docker 的 Python 脚本沙盒
- javascript - 更新 Observablehq 反应环境中的单元格值
- c++ - 如何在我们重建之前破坏布局Qt c++
- node.js - AWS Lambda 不独立运行
- javascript - HTML Canvas 绘制形状
- wkhtmltopdf - 如何在 php-buildpack (Cloud Foundry) 中运行/安装 wkhtmltopdf
- encryption - 使用 Apache Camel 进行 PGP 加密/解密:在密钥环中找不到密钥
- html - 如何将此 HTML 片段转换为引导程序
- maven - 如何将 SoapUI、Maven 和 HermesJMS 与 Jenkins 构建相结合?
- python - 具有空值的 ElasticSearch 过滤器查询