I want to pass an arbitrary object to the ThreadContext.put()
method like this:
MyObject originalMessage = new MyObject(...);
ThreadContext.put("originalMessage", originalMessage);
But that method only allows String
as its second argument: docs here.
Is there a way to put an arbitrary object in log4j in Log4j's MDC? Or an alternative to this? What I want is to allow further executions of log.error()
to automatically log the originalMessage
without need of passing it as a parameter everywhere.
Also, I can't invoke toString()
myself as I would be eagerly evaluating that method (which is quite heavy in this object), so I want its invocation to be delayed until it's needed, just like when you pass an arbitrary object to log.debug("{}", someObject)
.
I finally found a (hack) solution here and here.
Instead of this (which doesn't compile):
I can do:
This works as long as you add this JVM option:
Now, this looks hacky because getThreadContextMap() the method is supposed to return a read-only view of the internal map:
So this solution is casting that read-only map and, knowing the implementation is not read-only, modifying it ... not the most transparent solution but it works.