首页 > 解决方案 > 创建 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。

如果您需要更多信息,请告诉我。谢谢你。

标签: javaintellij-ideatomcat7jndilog4j2

解决方案


如果您需要更多信息,请告诉我。

在询问有关 Tomcat 的问题时,指定您使用的确切版本(xyz) 很重要。我希望您的 Tomcat 7.0.z 版本不是n岁。

当 Tomcat 尝试启动我的 webapp 时,它导致我的 webapp 失败。

错误消息说它是由方法“org.apache.catalina.deploy.NamingResources cleanUp”记录的。正如您可以从名称中猜到的那样,它不会在启动时发生,而是在关闭时发生。

日志文件和其他日志文件(尤其是 localhost.log)中的其他消息是什么?

我的猜测是其他东西阻止它启动,清理错误只是其后果。

静态 Logger 日志

为什么是“静态”?仅当您有此类的多个实例(并且希望跨实例共享记录器)时,这才有意义。如果只有一个实例(一个Servlet,一个Controller通常作为一个实例存在),使用实例字段更有意义。

一般注意事项:

  1. 常见故障排除提示。您可以尝试在 NamingResources 类中放置一个断点并查看它是如何启动的。您可以尝试在 StandardContext 类中放置一个断点并查看它是如何启动的。JNDI 在 StandardContext 启动序列的某个步骤初始化。
  2. 您可以尝试简化 Log4J 的配置。(以确保它不在其配置中使用 JNDI)。
  3. JNDI 通常是通过创建 InitialContext 并通过它进行查找来访问的。InitialContext 根据在其中运行的 Web 应用程序选择 JNDI 树。这是通过查看当前线程(又名 TCCL)的 Thread.getContextClassLoader() 来完成的。如果 TCCL 错误,JNDI 将无法访问。(NamingResources 类是一个例外,因为它可以访问 Tomcat 内部)。

推荐阅读