Warm tip: This article is reproduced from stackoverflow.com, please click
java logging maven log4j amazon-athena

Log4J ConsoleAppender is not assignable to Athena JDBC Driver

发布于 2020-03-29 21:00:22

I have trouble getting the Athena JDBC driver logging in place correctly. I'd favour SL4J SimpleLogger, but it seems this factory is not supported, but ust Log4J (just writing this in case you wonder why there's 2 logging framework). Unfortunately we do not want to change all current app logging because of one new jdbc driver.

When instantiating the logger without Log4J dependency I get a ClassNotFoundException, which is expected and shows Log4J is not included.

log4j:ERROR A "org.apache.log4j.ConsoleAppender" object is not assignable to a "com.simba.athena.shaded.apache.log4j.Appender" variable.
log4j:ERROR The class "com.simba.athena.shaded.apache.log4j.Appender" was loaded by 
log4j:ERROR [jdk.internal.loader.ClassLoaders$AppClassLoader@368239c8] whereas object of type 
log4j:ERROR "org.apache.log4j.ConsoleAppender" was loaded by [jdk.internal.loader.ClassLoaders$AppClassLoader@368239c8].
log4j:ERROR Could not instantiate appender named "stdout".

Maven Dependencies:

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>com.syncron.amazonaws</groupId>
            <artifactId>simba-athena-jdbc-driver</artifactId>
            <version>2.0.2</version>
        </dependency>

log4j.properties

### Appender
log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
log4j.appender.stdout.Target=System.out  
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

### Log Levels 
log4j.rootLogger=info, stdout  

It's kind of strange as both classes ARE loaded with the same classloader, so a classloader hierarchy issue shouldn't be the problem. I also verified the driver binds Log4J 1.2 as it points to that JavaDocs in some errors.

Would appreciate any hint from a Log4J expert. Thanks!

Questioner
supernova
Viewed
90
supernova 2020-02-17 05:41

Here's my findings after some time debugging classloading if someone experioences the same issues:

The Simba Athena driver provided by AWS comes with Log4J included. The Log4J Apache Classes are repackaged in a "shaded" package:

com.simba.athena.shaded.apache.log4j.Xyz

These classes will still load the apache configuration as expected like log4.properties file in the resources. The "standard" Apache Log4J classes will have troubles interoperating with those (e.g. the apache Appenders cannot be used in the log4j.properties which is loaded by the Athena driver because of this).

In the case you just want to get around the error messages created by the Athena driver (potentially not even using Log4J in the application like in the case I mentioned) you can address the Classes in the shaded packages within a standard 1.2 Log4J config and remove any Log4J dependencies from the build path.

Example:

Instead of

log4j.appender.Appender1=org.apache.log4j.ConsoleAppender

Use

log4j.appender.Appender1=com.simba.athena.shaded.apache.log4j.ConsoleAppender

I know it's not a perfect solution for all scenarios, but at least you can control errors spilled by the Athena driver this way.