Here is the specific issue I am encountering. I am using SLF4J Logger (The type of the variable logger
below)
//After adding to a map
logger debug ("Adding {} = {}", key, value)
Here is what mouse hover in eclipse (and the compiler) tell me.
ambiguous reference to overloaded definition, both method debug in trait Logger of type (x$1: String, x$2: Object*)Unit and method debug in trait Logger of type (x$1: String, x$2: Any, x$3: Any)Unit match argument types (String,String,String)
I understand why they are ambiguous. I am certainly not arguing with the compiler :). I want to simply know how seasoned programmers solve this issue.
Here are the alternatives I can use
Create and array , and ride the Object*
definition
logger debug ("Adding {} = {}", Array(key, value):_*)
Cast to Any
logger debug ("Adding {} = {}", key.asInstanceOf[Any], value.asInstanceOf[Any])
Neither approach is particularly appealing. Does the community have a better approach or suggestions for me?
Many thanks!
I would use
logger.debug("Adding {} = {}", key, value: Any)
Alternatively following can be used:
logger.debug("Adding {} = {}", Array(key, value):_*)
Please pay attention to :_*
. Should you omit these symbols and it will call Object*
method providing only 1 argument, which will be an array.
First off a nod of credit to @Shadowlands, @ArneClaassen and @OlgeRudenko. As mentioned in the comments, this does seem to be known issue. That stopped me from trying to "solve" it. The next thing to do was to find a good work around that did not break Scala idioms.
With these constraints in mind I chose to go with String Interpolation as suggested above. I also switched to scala-logging. Quoting from their GitHub/README,
Scala Logging is a convenient and performant logging library wrapping SLF4J. It's convenient, because you can simply call log methods without checking whether the respective log level is enabled:
logger.debug(s"Some $expensive message!")
It's performant, because thanks to Scala macros the check-enabled-idiom is applied, just like writing this more involved code:
if (logger.isDebugEnabled) logger.debug(s"Some $expensive message!")
Thanks all! As far as I am concerned, this is resolved. If the commentators can post their answers, I will be happy to acknowledge them.
As always, feels good to be standing on the shoulders of friendly giants!
PS: I just verified that there is no execution cost to String interpolation if you are using scala-logging. My verification method was crude but effective.
log.debug{
{
throw new IllegalAccessException("This should not have been called with debug off!")
}
s"Added Header ${name}:${headerValue}"
}
Sure enough, when I set my log to DEBUG
, the exception is thrown, as expected , but vanishes when I set it to a level higher.
And yes, I have already removed the IllegalAccessException
part :).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With