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)) {