{"record":{"id":"733c08ce60dc9a3c","repo":"pinpoint-apm/pinpoint","slug":"key","errorCode":null,"errorMessage":"key","messagePattern":"key","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/scope/ConcurrentPool.java","lineNumber":40,"sourceCode":"import java.util.concurrent.ConcurrentMap;\n\n/**\n * @author Woonduk Kang(emeroad)\n */\npublic class ConcurrentPool<K, V> implements Pool<K, V> {\n\n    private final ConcurrentMap<K, V> pool = new ConcurrentHashMap<K, V>();\n\n    private final PoolObjectFactory<K, V> objectFactory;\n\n    public ConcurrentPool(PoolObjectFactory<K, V> objectFactory) {\n        this.objectFactory = Objects.requireNonNull(objectFactory, \"objectFactory\");\n    }\n\n    @Override\n    public V get(K key) {\n        if (key == null) {\n            throw new IllegalArgumentException(\"key\");\n        }\n\n        final V alreadyExist = this.pool.get(key);\n        if (alreadyExist != null) {\n            return alreadyExist;\n        }\n\n        final V newValue = this.objectFactory.create(key);\n        final V oldValue = this.pool.putIfAbsent(key, newValue);\n        if (oldValue != null) {\n            return oldValue;\n        }\n        return newValue;\n    }\n\n\n}\n","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/scope/ConcurrentPool.java#L22-L58","documentation":"ConcurrentPool.get(K key) rejects null keys with IllegalArgumentException because null keys cannot be safely stored or looked up in the underlying ConcurrentHashMap and would defeat the factory-based lazy creation. Thrown at the very start of get().","triggerScenarios":"Calling pool.get(null) — typically when a caller derives the key (e.g. class name, method ID) from an upstream value that was itself null.","commonSituations":"Instrumentation code caching objects keyed by a classloader/class name that is unexpectedly null during bootstrap or unloaded classes.","solutions":["Check the key for null before calling get() and skip caching or throw a more descriptive error upstream","Trace where the key comes from and fix the producer of the null value","Use an explicit sentinel/Optional instead of null as a key"],"exampleFix":"// before\nV value = pool.get(keyMaybeNull);\n// after\nif (keyMaybeNull == null) {\n    throw new IllegalArgumentException(\"cache key must not be null\");\n}\nV value = pool.get(keyMaybeNull);","handlingStrategy":"validation","validationCode":"if (key == null) { throw new IllegalArgumentException(\"key must not be null before pool.get\"); }","typeGuard":"boolean validKey = (key != null);","tryCatchPattern":"try { V v = pool.get(key); } catch (IllegalArgumentException e) { logger.warn(\"null pool key\"); }","preventionTips":["Null-check keys derived from upstream values before caching","Use Objects.requireNonNull early at the source","Prefer Optional/sentinel over null keys"],"tags":["java","null-check","cache","arguments"],"backgroundTag":"null-argument","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}