{"record":{"id":"a5da4c4a12b40db5","repo":"pinpoint-apm/pinpoint","slug":"duplicated-pluginclass","errorCode":null,"errorMessage":"duplicated pluginClass {}","messagePattern":"duplicated pluginClass (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/PlainClassLoaderHandler.java","lineNumber":347,"sourceCode":"        public PluginLock getPluginLock(String jarFile) {\n            final PluginLock exist = this.pluginLock.get(jarFile);\n            if (exist != null) {\n                return exist;\n            }\n\n            final PluginLock newPluginLock = new PluginLock();\n            final PluginLock old = this.pluginLock.putIfAbsent(jarFile, newPluginLock);\n            if (old != null) {\n                return old;\n            }\n            return newPluginLock;\n        }\n\n        public void putClass(String className, Class<?> clazz) {\n            final Class<?> duplicatedClass = this.classCache.putIfAbsent(className, clazz);\n            if (duplicatedClass != null) {\n                if (logger.isWarnEnabled()) {\n                    logger.warn(\"duplicated pluginClass {}\", className);\n                }\n            }\n        }\n\n        public Class<?> getClass(String className) {\n            return this.classCache.get(className);\n        }\n\n        public boolean containsClass(String className) {\n            return this.classCache.containsKey(className);\n        }\n    }\n\n    private static class PluginLock {\n\n        private boolean loaded = false;\n\n        public boolean isLoaded() {","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/PlainClassLoaderHandler.java#L329-L365","documentation":"In PlainClassLoaderHandler's class cache, putClass uses putIfAbsent and logs this warn when a class with the same name is already cached, meaning two Class objects for one plugin class name were produced concurrently. The previously cached class wins; nothing is thrown. It usually indicates a race between concurrent define0 calls for the same class.","triggerScenarios":"Two threads concurrently defining/loading the same plugin class in the same classloader so putIfAbsent finds an existing entry; repeated plugin initialization racing during agent startup or class transformation.","commonSituations":"High-concurrency first-use of an instrumented class; plugin loaded by multiple matchers simultaneously; hot redeploy racing with in-flight requests.","solutions":["Verify the surviving cached class is the one actually used by all call sites (getClass returns the first).","Avoid racing plugin initialization — synchronize plugin setup at startup.","Check for duplicate plugin jars or duplicate transform requests for the same class.","If benign (same bytecode), this warn can be tolerated; otherwise investigate the concurrent define0 path."],"exampleFix":"// before\nfinal Class<?> dup = cache.putIfAbsent(className, clazz);\nif (dup != null) { logger.warn(\"duplicated pluginClass {}\", className); }\n// after\n// ensure single-threaded plugin class definition:\nsynchronized (defineLock) { cache.putIfAbsent(className, defineClass(className)); }","handlingStrategy":"validation","validationCode":"Class<?> existing = cache.get(className);\nif (existing != null) { return existing; } // skip redefinition","typeGuard":null,"tryCatchPattern":"synchronized (pluginDefineLock) { cache.putIfAbsent(className, defineClass(className)); }","preventionTips":["Define plugin classes single-threaded at startup","Cache-lookup before defining","Deduplicate plugin jars in the plugin directory","Log and reconcile any concurrent define0 races"],"tags":["classloader","plugin","concurrency","duplicate"],"backgroundTag":"duplicate-class-registration","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}