{"record":{"id":"b1fb05df70392bc6","repo":"pinpoint-apm/pinpoint","slug":"pluginconfig-getpluginjarurlexternalform-read","errorCode":null,"errorMessage":"${pluginConfig.getPluginJarURLExternalForm()} read fail.${ex.getMessage()}","messagePattern":"(.+?) read fail\\.(.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/PlainClassLoaderHandler.java","lineNumber":230,"sourceCode":"        List<FileBinary> fileBinaryList = readJar();\n\n        Map<String, SimpleClassMetadata> classEntryMap = parse(fileBinaryList);\n\n        for (Map.Entry<String, SimpleClassMetadata> entry : classEntryMap.entrySet()) {\n            final SimpleClassMetadata classMetadata = entry.getValue();\n            if (meetsRequirement(classMetadata.getClassName(), classLoader)) {\n                ClassLoadingChecker classLoadingChecker = new ClassLoadingChecker();\n                classLoadingChecker.isFirstLoad(classMetadata.getClassName());\n                define0(classLoader, attachment, classMetadata, classEntryMap, classLoadingChecker);\n            }\n        }\n    }\n\n    private List<FileBinary> readJar() {\n        try {\n            return pluginJarReader.read(ExtensionFilter.CLASS_FILTER);\n        } catch (IOException ex) {\n            throw new RuntimeException(pluginConfig.getPluginJarURLExternalForm() + \" read fail.\" + ex.getMessage(), ex);\n        }\n    }\n\n    private Map<String, SimpleClassMetadata> parse(List<FileBinary> fileBinaryList) {\n        Map<String, SimpleClassMetadata> parseMap = new HashMap<>();\n        for (FileBinary fileBinary : fileBinaryList) {\n            SimpleClassMetadata classNode = parseClass(fileBinary);\n            parseMap.put(classNode.getClassName(), classNode);\n        }\n        return parseMap;\n    }\n\n    private SimpleClassMetadata parseClass(FileBinary fileBinary) {\n        byte[] fileBinaryArray = fileBinary.getFileBinary();\n        return SimpleClassMetadataReader.readSimpleClassMetadata(fileBinaryArray);\n    }\n\n    private void define0(final ClassLoader classLoader, ClassLoaderAttachment attachment, SimpleClassMetadata currentClass, Map<String, SimpleClassMetadata> classMetaMap, ClassLoadingChecker classLoadingChecker) {","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/classloading/PlainClassLoaderHandler.java#L212-L248","documentation":"PlainClassLoaderHandler.readJar() reads all .class entries from the plugin jar via JarReader.read() to build class metadata. If any I/O error occurs while opening/reading the plugin jar, it rethrows it as a RuntimeException prefixed with the plugin jar's URL and the IOException message. This means the agent could not enumerate the plugin jar's class files, so plugin classes cannot be defined into the target classloader.","triggerScenarios":"Plugin class injection triggers defineJarClass() -> readJar() when a class from the plugin package must be defined into an application classloader; JarReader.read(ExtensionFilter.CLASS_FILTER) throws IOException because the jar is missing, corrupted, unreadable (permissions), deleted while the agent runs, or not a valid zip/jar (e.g. an HTML error page saved as a jar, or a truncated download).","commonSituations":"Wrong pinpoint plugin dir configured so the 'jar' is a placeholder or partial download; corrupted plugin jar after a failed in-place upgrade while the agent was running; file permissions changed by deployment tooling; disk/network mount issues making the jar unreadable; broken plugin packaging step.","solutions":["Verify the plugin jar at the URL printed in the message exists and is a valid jar: run `unzip -t <pluginJarPath>`; re-download/rebuild the plugin if the test fails.","Check file read permissions for the user running the pinpoint agent on the plugin jar and its directory (chmod/chown as needed).","Confirm profiler.plugin.dir (or equivalent plugin config) points to the real plugin directory, not a staging/temp path that has been cleaned up.","Restart the agent after replacing/upgrading plugin jars so PluginConfig references a fresh, stable File instead of a deleted one.","Inspect the wrapped IOException cause for the underlying reason (file not found vs. missing zip END_HEADER) and fix accordingly."],"exampleFix":"# before (invalid/corrupted jar)\nls $AGENT_HOME/plugin\ntomcat-instrumentation-0.0.1-SNAPSHOT.jar  # 12 bytes, partial download\n# after\nmv tomcat-instrumentation-0.0.1-SNAPSHOT.jar /tmp/broken.jar\nmv ~/.m2/.../tomcat-instrumentation-0.0.1-SNAPSHOT.jar $AGENT_HOME/plugin/\nunzip -t $AGENT_HOME/plugin/tomcat-instrumentation-0.0.1-SNAPSHOT.jar  # 'No errors detected'","handlingStrategy":"validation","validationCode":"// before starting the agent, validate every plugin jar\nFile pluginJar = new File(pluginDir, \"my-plugin.jar\");\nif (!pluginJar.isFile() || pluginJar.length() == 0) throw new IllegalStateException(\"missing plugin jar\");\ntry (JarFile jf = new JarFile(pluginJar)) {\n    if (jf.getEntry(\"com/myplugin/MyPlugin.class\") == null) throw new IllegalStateException(\"plugin jar incomplete\");\n} catch (IOException e) { throw new IllegalStateException(\"corrupted/unreadable plugin jar: \" + pluginJar, e); }","typeGuard":"static boolean isReadableJar(File f) {\n    try (JarFile jf = new JarFile(f)) { return f.canRead(); }\n    catch (IOException e) { return false; }\n}","tryCatchPattern":"try {\n    injector.injectClass(cl, className);\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof IOException && e.getMessage().contains(\"read fail.\")) {\n        logger.error(\"plugin jar unreadable: {}\", pluginJarPath, e.getCause());\n        // fail fast or degrade without this plugin\n    } else throw e;\n}","preventionTips":["Validate plugin jars with `unzip -t` in the deployment pipeline before shipping to the agent host.","Never replace plugin jars in place while the agent runs; restart after upgrades.","Pin plugin jar versions and verify checksums after download.","Ensure the user running the JVM has read access to $AGENT_HOME/plugin/."],"tags":["java","pinpoint-agent","plugin-loading","io","corrupted-jar"],"backgroundTag":"file-read-failed","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"}