简体   繁体   中英

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 than logs to all or none of the underlying implementations.

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 package s (eg 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 between direct invocation and 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 eg via log4j without its decision making)?

You could change the access to public by creating you own version of the code, or

you could use a sub-classed Logger instead.

The simplest solution is likely to be to use reflection. I would check your application server doesn't prevent this as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM