ClasscastException - org.apache.log4j.Logger cannot be cast to org.owasp.esapi.Logger - log4j to log4j2

You can switch the logger factory away from the Log4j1 factory in the ESAPI.properties file to something else in order to avoid this error. I haven't tried but I imagine you could create a custom logging factory that uses Log4j2.

The following example will configure ESAPI to use JUL logging, which avoids the ClassCastException:

ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactory


This problem isn't solvable.

ESAPI has a hard dependency on Log4J 1.x and doesn't at present support Log4j2.

There is an open enhancement to use slf4j which might support Log4j2 indirectly, but at present this isn't being worked.


This problem is solvable, but it is not a nice solution and it is situational.

I've had the same problem as ATK. I ended up using the same bridge-api as ATK for the other packages, but for ESAPI there is a nasty workaround.

My situation: I have only tested this on Jetty and Tomcat application servers. I have my own logging library wrapping around log4j2 and I use Scala, not Java.

First off, the class that creates the ClassCastException is org.owasp.esapi.reference.Log4JLogFactory.

I ended up creating the package org.owasp.esapi.reference and created my own Scala object named Log4JLogFactory. This object extends my own logging framework (named "Logging" in the upcoming example) and implements the org.owasp.esapi.LogFactory interface. To implement these methods, I just pass on the logging message to my own logging framework. So the log.error(...) method calls comes from my own logger, and to implement this solution you will need your own.

object Log4JLogFactory extends Logging with org.owasp.esapi.LogFactory {
  private[reference] lazy val factory = new Log4JLoggerFactory
  def getInstance = {
    this
  }

  private val logger = new org.owasp.esapi.Logger {
    override def error(`type`: Logger.EventType, message: String) = log.error(message)

    override def error(`type`: Logger.EventType, message: String, throwable: Throwable) = log.error(message, throwable)

    // implement the rest of the methods that is needed...
  }

  override def getLogger(clazz: Class[_]) = logger

  override def getLogger(moduleName: String) = logger
}

NB! This solution works on Jetty and Tomcat. Application servers that doesn't load your own classes before library classes will not work with this solution.