{"record":{"id":"e6fea8b287431de8","repo":"HMCL-dev/HMCL","slug":"game-processor-jar-does-not-have-main-class","errorCode":null,"errorMessage":"Game processor jar does not have main class ","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/forge/ForgeNewInstallTask.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/forge/ForgeNewInstallTask.java#L104-L140","documentation":"Thrown when the processor JAR exists but its manifest has no Main-Class attribute (or it is blank). HMCL launches each Forge processor via 'java -cp <jar> <mainClass>'; without a main class in the manifest it cannot determine what to execute. It is a plain Exception propagated out of ProcessorTask.execute().","triggerScenarios":"The processor jar file in the repository is corrupted, empty, or not an executable jar (e.g. an HTML error page saved as .jar, a truncated download, or a jar-repack that dropped META-INF/MANIFEST.MF).","commonSituations":"Proxy/CDN serving an error page in place of the jar; interrupted download leaving a zero-byte file; antivirus quarantining and rewriting jar files.","solutions":["Delete the corrupt processor jar from the libraries directory and re-run installation to re-download it","Verify the jar opens with 'jar tf' and its MANIFEST.MF has a Main-Class entry","Check the downloaded file's size/SHA-1 against the Forge maven metadata","Exclude the game directory from antivirus interference and retry"],"exampleFix":"// before: blindly trusting a 0-byte jar\nPath jar = Paths.get(\"libraries/net/minecraftforge/installertools/1.3.0/installertools-1.3.0.jar\");\n// after: sanity-check before running install task\nif (Files.size(jar) < 1024) {\n    Files.delete(jar); // force re-download\n}\nnew ForgeNewInstallTask(dependencyManager, manifest, minecraftJar, version, installer);","handlingStrategy":"validation","validationCode":"// Verify processor jars are real, executable jars before install\ntry (JarFile jf = new JarFile(jarPath.toFile())) {\n    String mc = jf.getManifest() == null ? null : jf.getManifest().getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);\n    if (mc == null || mc.isBlank()) { Files.delete(jarPath); throw new IOException(\"Bad processor jar, re-download\"); }\n}","typeGuard":null,"tryCatchPattern":"try {\n    installTask.run();\n} catch (Exception e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Game processor jar does not have main class\")) {\n        // delete the jar and re-download libraries, then retry\n    }\n}","preventionTips":["Verify downloaded jar sizes/hashes against Forge maven metadata","Exclude the game directory from antivirus that rewrites/quarantines jars","Clear partial downloads after interrupted installs"],"tags":["forge","jar-manifest","processor"],"backgroundTag":"missing-dependency","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}