Search code examples
javaintellij-ideatomcat7jndilog4j2

Creating a log4j2 Logger causes retrieval of JNDI naming context to fail when starting Tomcat webapp


I have a Java 7 webapp I'm trying to get working on a server running Tomcat 7.0.53. Before trying to use Log4j, my webapp has been able to start and run with no problems.

Now, I'm trying to add and use Log4j2 in my app. By commenting out the line of code that creates a Log4j Logger, I've discovered that it is causing my webapp to fail when Tomcat attempts to start my webapp. Here is the specific error from 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

The NamingException occurs because the lookup of java:comp/env fails.

This is the specific line of code which causes the above warning and subsequent exception:

static Logger log = LogManager.getLogger( DBTest.class.getName() );

The IDE I'm using is Intellij IDEA.

Please let me know if you need any more information. Thank you.


Solution

  • Please let me know if you need any more information.

    When asking questions about Tomcat, it is important to specify what exact version (x.y.z) you are using. I hope that your version of Tomcat 7.0.z is not n years old.

    it is causing my webapp to fail when Tomcat attempts to start my webapp.

    The error message says that it is logged by method "org.apache.catalina.deploy.NamingResources cleanUp". As you can guess from the name, it does not happen at startup, but at shutdown.

    What are the other messages in the log file, and in another log files (localhost.log in particular)?

    My guess is that something else prevents it from starting, and the cleanup error is just an aftermath of that.

    static Logger log

    Why "static"? This makes sense only if you have several instances of this class (and want to share the logger across instances). If there is only one instance (a Servlet, a Controller usually exists as a single instance), using an instance field makes more sense.

    General notes:

    1. Common troubleshooting tips. You may try to put a breakpoint in NamingResources class and look how it starts up. You may try to put a breakpoint in StandardContext class and look how it starts up. JNDI is initialized at certain step of StandardContext startup sequence.
    2. You may try to simplify your configuration of Log4J. (To ensure that it does not use JNDI in its configuration).
    3. JNDI is usually access by creating an InitialContext and doing a lookup through it. The InitialContext selects JNDI tree according to the web application that it runs within. This is done by looking at Thread.getContextClassLoader() of the current thread (aka TCCL). If TCCL is wrong, JNDI won't be accessible. (The NamingResources class is an exception, because it has access to Tomcat internals).