From 5c8e93fd95497a36998f6cb6902502ac15c18afb Mon Sep 17 00:00:00 2001 From: SashegDev Date: Mon, 13 Jul 2026 13:43:29 +0000 Subject: [PATCH] fix: include net.minecraft libs in classpath for Forge module path resolution Forge version.json uses -p ${classpath} to set the module path to the same argfile as the classpath. Previously we filtered net.minecraft:* libs from the classpath string, which meant they were absent from the module path too, causing ClassNotFoundException for PreparableReloadListener and other MC classes. Now net.minecraft:* libs are included in the Forge classpath argfile so securejarhandler can load them as modules. --- .../minecraft/launch/LaunchCommandBuilder.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/minecraft/launch/LaunchCommandBuilder.java b/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/minecraft/launch/LaunchCommandBuilder.java index da05ce9..69974de 100644 --- a/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/minecraft/launch/LaunchCommandBuilder.java +++ b/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/minecraft/launch/LaunchCommandBuilder.java @@ -501,14 +501,11 @@ public class LaunchCommandBuilder { boolean isForgeLike = "forge".equals(loaderType) || "neoforge".equals(loaderType); for (VersionManifest.Library lib : manifest.getAllLibraries()) { - // For Forge/NeoForge: skip Minecraft client libraries — they're loaded - // through Forge's own module system (securejarhandler + module path). - // Having them on the classpath creates automatic modules that conflict - // with Forge's own module layer (split-package ResolutionException). - if (isForgeLike && lib.name.startsWith("net.minecraft:")) { - System.out.println(ZAnsi.cyan(" Skipping Minecraft lib (loaded via module system): " + lib.name)); - continue; - } + // For Forge/NeoForge: include ALL libraries including net.minecraft:* + // in the classpath string. Forge version.json uses "-p ${classpath}" to + // set BOTH classpath and module path to the same string. The Minecraft + // client JAR must be on the module path so securejarhandler can load it + // as a proper module. Skipping it causes ClassNotFoundException. Path libPath = lib.artifactPath != null ? librariesDir.resolve(lib.artifactPath) : null; if (libPath != null && Files.exists(libPath)) { if (isValidJar(libPath)) {