{"record":{"id":"61a628adac1d4bd2","repo":"HMCL-dev/HMCL","slug":"game-processor-jar-does-not-have-main-class-jar","errorCode":null,"errorMessage":"Game processor jar does not have main class ${jar}","messagePattern":"Game processor jar does not have main class (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/download/neoforge/NeoForgeOldInstallTask.java","lineNumber":122,"sourceCode":"                    miss = true;\n                }\n            }\n\n            if (!processor.getOutputs().isEmpty() && !miss) {\n                return;\n            }\n\n            Path jar = gameRepository.getLayout().getArtifactFile(processor.getJar());\n            if (!Files.isRegularFile(jar))\n                throw new FileNotFoundException(\"Game processor file not found, should be downloaded in preprocess\");\n\n            String mainClass;\n            try (JarFile jarFile = new JarFile(jar.toFile())) {\n                mainClass = jarFile.getManifest().getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);\n            }\n\n            if (StringUtils.isBlank(mainClass))\n                throw new Exception(\"Game processor jar does not have main class \" + jar);\n\n            List<String> command = new ArrayList<>();\n            command.add(JavaRuntime.getDefault().getBinary().toString());\n            command.add(\"-cp\");\n\n            List<String> classpath = new ArrayList<>(processor.getClasspath().size() + 1);\n            for (Artifact artifact : processor.getClasspath()) {\n                Path file = gameRepository.getLayout().getArtifactFile(artifact);\n                if (!Files.isRegularFile(file))\n                    throw new Exception(\"Game processor dependency missing\");\n                classpath.add(file.toString());\n            }\n            classpath.add(jar.toString());\n            command.add(String.join(File.pathSeparator, classpath));\n\n            command.add(mainClass);\n\n            List<String> args = new ArrayList<>(processor.getArgs().size());","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/download/neoforge/NeoForgeOldInstallTask.java#L104-L140","documentation":"Thrown when the processor jar exists but its MANIFEST.MF has no Main-Class attribute (or it is blank). HMCL executes each install processor as `java -cp <jar+classpath> <mainClass>`; without a Main-Class there is no entry point, so the processor configuration is unusable.","triggerScenarios":"Files.isRegularFile(jar) passed and the JarFile manifest lookup returns null/blank for Attributes.Name.MAIN_CLASS — i.e. a downloaded processor jar that is not an executable jar (corrupted download, wrong artifact, HTML error page saved as jar, or a changed processor spec).","commonSituations":"Corrupted or truncated download of a Forge/NeoForge processor library; a proxy/mirror serving an error page in place of the jar; manually replaced jar from a wrong version; running an installer whose processor metadata comes from an incompatible (modded/hacked) install_profile.json.","solutions":["Delete the offending jar from the libraries directory and re-run the install so it is re-downloaded","Verify the jar by opening it (it should be a valid zip with MANIFEST.MF containing Main-Class) and check its size/SHA-1","Switch to a working download mirror and retry","Use an official/unmodified NeoForge installer jar; a modified install_profile.json can reference a non-executable jar"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"try (JarFile jf = new JarFile(jar.toFile())) {\n    String mc = jf.getManifest() == null ? null : jf.getManifest().getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);\n    if (mc == null || mc.isBlank()) reDownload(jar);\n}","typeGuard":null,"tryCatchPattern":"try { task.run(); } catch (Exception e) { if (e.getMessage() != null && e.getMessage().startsWith(\"Game processor jar does not have main class\")) reDownloadCorruptJar(); else throw e; }","preventionTips":["Verify jar integrity (SHA-1/size) after download","Use trusted mirrors; an HTML error page saved as a jar lacks a manifest","Keep installer and libraries from the same version set"],"tags":["java","jar","manifest","installer"],"backgroundTag":"file-not-found","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}