Uploaded image for project: 'Hippo CMS'
  1. Hippo CMS
  2. CMS-10991

ClassNotFoundException: org.apache.naming.java.javaURLContextFactory in Log4j2 LookupFilter when invoked from System FinalizerThread

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Normal
    • Resolution: Fixed
    • Affects Version/s: commons-4.0.0
    • Fix Version/s: commons-4.0.2, commons-4.1.0
    • Component/s: None
    • Labels:
      None
    • Similar issues:
    • Story Points:
      1
    • Processed by team:
      Platform
    • Sprint:
      Platform 170

      Description

      The Log4j2 LookupFilter is typicallly used for Context Based Logging.
      This uses a JNDI lookup of the current context to determine to which log file a LogEvent should be logged.

      This normally works just fine, but it fails when the logging is invoked through the Java System FinalizerThread, leading to for example the following stack trace:

      Finalizer ERROR Error creating JNDI InitialContext. javax.naming.NoInitialContextException: Cannot instantiate class: org.apache.naming.java.javaURLContextFactory [Root exception is java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory]
       	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:674)
       	at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
       	at javax.naming.InitialContext.init(InitialContext.java:244)
       	at javax.naming.InitialContext.<init>(InitialContext.java:216)
       	at org.apache.logging.log4j.core.net.JndiManager$JndiManagerFactory.createManager(JndiManager.java:137)
       	at org.apache.logging.log4j.core.net.JndiManager$JndiManagerFactory.createManager(JndiManager.java:132)
       	at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:112)
       	at org.apache.logging.log4j.core.net.JndiManager.getDefaultManager(JndiManager.java:53)
       	at org.apache.logging.log4j.core.lookup.JndiLookup.lookup(JndiLookup.java:53)
       	at org.apache.logging.log4j.core.lookup.Interpolator.lookup(Interpolator.java:183)
       	at org.onehippo.cms7.logging.log4j.LookupFilter.filter(LookupFilter.java:98)
       	at org.apache.logging.log4j.core.filter.AbstractFilterable.isFiltered(AbstractFilterable.java:182)
       	at org.apache.logging.log4j.core.config.AppenderControl.isFilteredByAppender(AppenderControl.java:151)
       	at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:128)
       	at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
       	at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
       	at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:448)
       	at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:433)
       	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:417)
       	at org.apache.logging.log4j.core.config.LoggerConfig.logParent(LoggerConfig.java:439)
       	at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:434)
       	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:417)
       	at org.apache.logging.log4j.core.config.LoggerConfig.logParent(LoggerConfig.java:439)
       	at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:434)
       	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:417)
       	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:403)
       	at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:63)
       	at org.apache.logging.log4j.core.Logger.logMessage(Logger.java:146)
       	at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2091)
       	at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:1988)
       	at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1960)
       	at org.apache.logging.slf4j.Log4jLogger.warn(Log4jLogger.java:259)
       	at org.apache.jackrabbit.core.SessionImpl.finalize(SessionImpl.java:1381)
       	at java.lang.System$2.invokeFinalize(System.java:1270)
       	at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:98)
       	at java.lang.ref.Finalizer.access$100(Finalizer.java:34)
       	at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:210)
       Caused by: java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory
       	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
       	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
       	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
       	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
       	at java.lang.Class.forName0(Native Method)
       	at java.lang.Class.forName(Class.java:348)
       	at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:72)
       	at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:61)
       	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:672)

      The above example is triggered by a not-properly logged out Jackrabbit SessionImpl, which then will (try to) log a warning in its finalize method (logging the origin of the session creation).

      The underlying problem is: the Java System FinalizerThread does not have a Thread contextClassLoader!
      And thus (at least when using Tomcat, but likely this will happen in any application container), trying to construct a JNDI InitialContext object will result in the above ClassNotFoundException.

      The solution for this specific problem turns out to be rather trivial: if the current Thread does not have a context classloader (which in practice should only happen with something like the System FinalizerThread) then temporarily assign the current class (LookupFilter in this case) as context classloader, before trying doing the lookup.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              adouma Ate Douma
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: