{"record":{"id":"82e3a25b86966965","repo":"pinpoint-apm/pinpoint","slug":"cannot-access-urlclassloader-addurl-url","errorCode":null,"errorMessage":"Cannot access URLClassLoader.addURL(URL)","messagePattern":"Cannot access URLClassLoader\\.addURL\\(URL\\)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/URLClassLoaderHandler.java","lineNumber":46,"sourceCode":"import java.util.Objects;\n\n/**\n * @author Woonduk Kang(emeroad)\n * @author jaehong.kim\n */\npublic class URLClassLoaderHandler implements ClassInjector {\n\n    private final Logger logger = LogManager.getLogger(this.getClass());\n    private final boolean isDebug = logger.isDebugEnabled();\n\n    private static final Method ADD_URL;\n\n    static {\n        try {\n            ADD_URL = URLClassLoader.class.getDeclaredMethod(\"addURL\", URL.class);\n            ADD_URL.setAccessible(true);\n        } catch (ReflectiveOperationException e) {\n            throw new IllegalStateException(\"Cannot access URLClassLoader.addURL(URL)\", e);\n        }\n    }\n\n    private final PluginConfig pluginConfig;\n\n    public URLClassLoaderHandler(PluginConfig pluginConfig) {\n        this.pluginConfig = Objects.requireNonNull(pluginConfig, \"pluginConfig\");\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public <T> Class<? extends T> injectClass(ClassLoader classLoader, String className) {\n        try {\n            if (classLoader instanceof URLClassLoader) {\n                final URLClassLoader urlClassLoader = (URLClassLoader) classLoader;\n                addPluginURLIfAbsent(urlClassLoader);\n                return (Class<T>) urlClassLoader.loadClass(className);\n            }","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/URLClassLoaderHandler.java#L28-L64","documentation":"URLClassLoaderHandler appends the plugin jar to URLClassLoader-based application classloaders by reflectively invoking the protected URLClassLoader.addURL(URL) method, resolved once in a static initializer with setAccessible(true). If the JVM cannot expose addURL (module encapsulation, SecurityManager, or JVM without the method), the static initializer throws IllegalStateException, failing agent startup. This handler is only used when the target classloader is a URLClassLoader.","triggerScenarios":"Agent startup instantiates URLClassLoaderHandler (from PluginClassInjector.from) and the static block runs: URLClassLoader.class.getDeclaredMethod(\"addURL\", URL.class) fails or setAccessible(true) is rejected on JDK 9+ without --add-opens java.base/java.net=ALL-UNNAMED, or a SecurityManager denies ReflectPermission(\"suppressAccessChecks\").","commonSituations":"Running the agent on JDK 16+ where default strong encapsulation blocks setAccessible on JDK internals; legacy SecurityManager policies applied to containerized apps; a custom/alternative JDK that hides protected addURL.","solutions":["Add --add-opens java.base/java.net=ALL-UNNAMED (and java.lang if the plain handler also fails) to the application's JVM launch flags.","Grant ReflectPermission(\"suppressAccessChecks\") to the pinpoint agent in the SecurityManager policy, or remove the SecurityManager if not required.","Upgrade the pinpoint agent to a version supporting your JDK's encapsulation rules, or use a supported JDK combination.","Confirm the application actually launches with a URLClassLoader and a supported launcher for the agent version.","Check startup logs for the full IllegalStateException cause to distinguish 'method missing' from 'access denied'."],"exampleFix":"// before\njava -cp app.jar:legacy.jar com.app.Main\n// after\njava --add-opens java.base/java.net=ALL-UNNAMED -javaagent:$AGENT_HOME/pinpoint-bootstrap.jar -cp app.jar com.app.Main","handlingStrategy":"validation","validationCode":"// preflight: confirm addURL is reflectively accessible before starting the agent\nboolean canAddUrl = false;\ntry {\n    Method m = URLClassLoader.class.getDeclaredMethod(\"addURL\", URL.class);\n    m.setAccessible(true);\n    canAddUrl = true;\n} catch (ReflectiveOperationException e) {\n    System.err.println(\"Agent unsupported: need --add-opens java.base/java.net=ALL-UNNAMED\");\n}\nif (!canAddUrl) throw new IllegalStateException(\"JVM blocks URLClassLoader.addURL reflection; add --add-opens flags\");","typeGuard":"static boolean supportsReflectiveAddURL() {\n    try {\n        Method m = URLClassLoader.class.getDeclaredMethod(\"addURL\", URL.class);\n        m.setAccessible(true);\n        return true;\n    } catch (ReflectiveOperationException | SecurityException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    agentBootstrap.start();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Cannot access URLClassLoader.addURL\")) {\n        System.err.println(\"Restart JVM with: --add-opens java.base/java.net=ALL-UNNAMED\");\n    } else throw e;\n}","preventionTips":["Add --add-opens java.base/java.net=ALL-UNNAMED to launch scripts for apps using URLClassLoader-based loaders.","Validate agent/JDK compatibility (especially JDK 16+ default encapsulation) in staging before upgrades.","Review SecurityManager policy files when migrating legacy apps to containers.","Prefer standard supported JDK builds when running pinpoint agents."],"tags":["java","reflection","pinpoint-agent","urlclassloader","jdk9-modules","startup"],"backgroundTag":"reflective-access-denied","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}