mardi 15 septembre 2015

Is there a way to access protected class members from different runtime package without reflection?

I'm making a JCL logging bridge that operates over several (let's say two) logging implementations (like log4j). Depending on configuration of all these implementations the bridge than makes custom global decision whether to log and logs to all or non of the implementations.

Now logging implementations usually have methods like this:

  • public isLevelEnabled() to test "loggability"
  • public logLevel(msg) which use the test methods and eventually logs messages via ->
  • protected logInternal(lvl, msg) which logs without additional tests

Now since I make custom decision if level is enabled, I cannot use the public log methods that make the standard decision and I need to use the protected method directly.

I know, that I can access the protected members from the same package so I added an "intruder" class with the same package as the logger class of target implementation:

package com.log.lib;

//logging library logger in dependency jar
public class Logger {
  protected void logInternal(int lvl, String msg){
    //library logging without additional level testing
  }
}

package com.log.lib;

//my class to access protected method of library logger
public class LoggerAccessor {
  public void log(Logger logger, int lvl, String msg) {
    logger.logInternal(lvl, msg);
  }
}

This worked fined until I ran the code on an application server which provides one of the logging implementations loaded by different classloader than my application. I got an IllegalAccessException. So this is how I learned about runtime packages (e.g. quick explanation here).

I can invoke the method via reflection by granting accessibility and I even have an automatic test of runtime package and select direct invocation or reflection. But the reflection is always used on the application server where the application runs. And since logging is an extensively used activity the reflection is kind of bottleneck here.

So I ask: Is there a better (faster) way to invoke the protected method from different runtime package (or to log e.g. via log4j without its decision making)?





Aucun commentaire:

Enregistrer un commentaire