I've written a little wrapper for SLF4J MDC.
import org.slf4j.MDC;
import java.util.UUID;
public final class MdcWrapperUtility {
public static final String MDC_TRANSACTION_ID_KEY_NAME = "MDC_TRANSACTION_ID";
private MdcWrapperUtility() {
}
public static String getId() {
String threadName = Thread.currentThread().getName();
String returnValue = MDC.get(MDC_TRANSACTION_ID_KEY_NAME);
return returnValue;
}
public static String setId() {
String threadName = Thread.currentThread().getName();
String uuid = UUID.randomUUID().toString();
String setAndReturnValue = threadName + uuid;
MDC.put(MDC_TRANSACTION_ID_KEY_NAME, setAndReturnValue);
String sanityCheck = MDC.get(MDC_TRANSACTION_ID_KEY_NAME);
if (null == sanityCheck || sanityCheck.length() <= 0)
{
throw new NullPointerException("MDC did not persist. How is this even happening?????");
}
return setAndReturnValue;
}
}
At first, after I called "setId()"...i would later call "getId" and it would be null. You can see that I DID verify the thread names...understanding "the thread" is the "magic" that allows MDC to work.
So then I did an MDC.get IMMEDIATELY after the MDC.put, and it is coming back as null.
???
Gaaa.
In my proof of concept project I have:
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
implementation group: 'org.slf4j', name: 'slf4j-simple', version: slf4jSimpleVersion
Exact versions below:
slf4jSimpleVersion = '1.7.30'
slf4jVersion = '1.7.30'
Both proof-of-concept and "real" give me a null MDC.get (aka, I get the "MDC did not persist. How is this even happening?????" exception.
The only other clue I can offer is that I do NOT have a monolith. I have a multi module gradle project.
https://docs.gradle.org/current/userguide/multi_project_builds.html
I am using variables (defined in my root build.gradle) for my versions, so I do not have a mismatch version in any module(s).
APPEND ONE:
Ok, so I know why it is returning "null". It is using the concrete
public class NOPMDCAdapter implements MDCAdapter {
public void clear() {
}
public String get(String key) {
return null;
}
public void put(String key, String val) {
}
public void remove(String key) {
}
public Map<String, String> getCopyOfContextMap() {
return null;
}
public void setContextMap(Map<String, String> contextMap) {
// NOP
}
}
.........