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

11,514

Solution 1

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.

Solution 2

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

Solution 3

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.

Solution 4

I solved a similar problem by adding this to log4j.xml

<loggerFactory class="org.owasp.esapi.reference.Log4JLoggerFactory"/>
Share:
11,514
ATK
Author by

ATK

Updated on June 17, 2022

Comments

  • ATK
    ATK almost 2 years

    I am working on upgrading log4j to log4j2. In that process I am getting a Logger Class cast exception. Below is the error.

    Caused by: java.lang.ClassCastException: org.apache.log4j.Logger cannot be cast to org.owasp.esapi.Logger
        at org.owasp.esapi.reference.Log4JLogFactory.getLogger(Log4JLogFactory.java:88)
        at org.owasp.esapi.ESAPI.getLogger(ESAPI.java:154)
        at org.owasp.esapi.reference.DefaultEncoder.<init>(DefaultEncoder.java:75)
        at org.owasp.esapi.reference.DefaultValidator.<clinit>(DefaultValidator.java:91)
        ... 45 more
    

    In my old code( log4j properties file) I see a reference to this Logger. Below is the code that we have in our old code.

    log4j.loggerFactory=org.owasp.esapi.reference.Log4JLoggerFactory
    

    Now in log4j2 I am using log4j2.xml file and I didn't find any tag equivalent to that line. Could any please suggest me how to proceed?
    Note: I am running my application in JBoss EAP 7