fix: ensure version jar exists for Forge to prevent _1._20._1 module name
findVersionJar() falls back to versions/1.20.1/1.20.1.jar when the Forge version jar doesnt exist. Filename 1.20.1.jar produces automatic module _1._20._1 which conflicts with module minecraft (split-package on net.minecraft.server). Fix: ensureVersionJarForForge() copies vanilla jar to versions/<versionId>/ <versionId>.jar before findVersionJar() is called. Vanilla jar has Automatic-Module-Name: minecraft so it becomes module minecraft, not _1._20._1.
This commit is contained in:
+18
-30
@@ -59,6 +59,11 @@ public class LaunchCommandBuilder {
|
|||||||
// defines all of these. This matches AstralRinth's approach.
|
// defines all of these. This matches AstralRinth's approach.
|
||||||
System.out.println(ZAnsi.cyan(" Forge/NeoForge: using version.json args with placeholder substitution"));
|
System.out.println(ZAnsi.cyan(" Forge/NeoForge: using version.json args with placeholder substitution"));
|
||||||
|
|
||||||
|
// Ensure version jar exists at versions/<versionId>/<versionId>.jar
|
||||||
|
// so securejarhandler creates module "minecraft" (from Automatic-Module-Name)
|
||||||
|
// instead of "_1._20._1" (automatic module from filename 1.20.1.jar).
|
||||||
|
ensureVersionJarForForge();
|
||||||
|
|
||||||
// Build classpath from manifest libraries + client jar
|
// Build classpath from manifest libraries + client jar
|
||||||
String classpath;
|
String classpath;
|
||||||
if (manifest != null) {
|
if (manifest != null) {
|
||||||
@@ -698,17 +703,13 @@ public class LaunchCommandBuilder {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure the version jar exists at versions/<versionId>/<versionId>.jar
|
* Ensure the version jar exists at versions/<versionId>/<versionId>.jar
|
||||||
* so that securejarhandler can create the "minecraft" module from it.
|
* so that securejarhandler creates module "minecraft" (from
|
||||||
|
* Automatic-Module-Name: minecraft) instead of "_1._20._1" (automatic
|
||||||
|
* module derived from filename 1.20.1.jar).
|
||||||
*
|
*
|
||||||
* The version jar MUST contain SRG-mapped classes (not obfuscated Mojang
|
* Without this, findVersionJar() falls back to versions/1.20.1/1.20.1.jar
|
||||||
* names) and have Automatic-Module-Name: minecraft in its MANIFEST.MF.
|
* which produces module _1._20._1, causing split-package conflicts with
|
||||||
* Without this, securejarhandler creates an automatic module from the
|
* the minecraft module.
|
||||||
* filename, claims the net.minecraft.server.packs.resources package, but
|
|
||||||
* doesn't have SRG-named classes like PreparableReloadListener → crash.
|
|
||||||
*
|
|
||||||
* Priority:
|
|
||||||
* 1. SRG-mapped client jar from Forge libraries (client-*-srg.jar)
|
|
||||||
* 2. Vanilla version jar (fallback, may cause module issues)
|
|
||||||
*/
|
*/
|
||||||
private void ensureVersionJarForForge() throws IOException {
|
private void ensureVersionJarForForge() throws IOException {
|
||||||
String versionId = getVersionId();
|
String versionId = getVersionId();
|
||||||
@@ -719,34 +720,21 @@ public class LaunchCommandBuilder {
|
|||||||
Path targetJar = targetDir.resolve(versionId + ".jar");
|
Path targetJar = targetDir.resolve(versionId + ".jar");
|
||||||
|
|
||||||
if (Files.exists(targetJar) && isValidJar(targetJar)) {
|
if (Files.exists(targetJar) && isValidJar(targetJar)) {
|
||||||
if (hasMinecraftModuleName(targetJar)) {
|
System.out.println(ZAnsi.green(" Version jar already exists: " + targetJar));
|
||||||
System.out.println(ZAnsi.green(" Version jar already exists with correct module name: " + targetJar));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println(ZAnsi.yellow(" Version jar exists but missing Automatic-Module-Name: minecraft — overwriting with SRG jar"));
|
|
||||||
Files.delete(targetJar);
|
|
||||||
}
|
|
||||||
|
|
||||||
Files.createDirectories(targetDir);
|
Files.createDirectories(targetDir);
|
||||||
|
|
||||||
// Priority 1: SRG-mapped client jar from Forge libraries
|
// Copy vanilla client jar — it has Automatic-Module-Name: minecraft
|
||||||
// This jar has Automatic-Module-Name: minecraft and correct SRG class names
|
Path vanillaJar = versionsDir.resolve(mcVersion).resolve(mcVersion + ".jar");
|
||||||
Path srgJar = findSrgClientJar();
|
if (Files.exists(vanillaJar) && isValidJar(vanillaJar)) {
|
||||||
if (srgJar != null && isValidJar(srgJar)) {
|
Files.copy(vanillaJar, targetJar);
|
||||||
Files.copy(srgJar, targetJar);
|
System.out.println(ZAnsi.green(" Copied vanilla jar for securejarhandler: " + vanillaJar.getFileName() + " → " + targetJar));
|
||||||
System.out.println(ZAnsi.green(" Copied SRG client jar for securejarhandler: " + srgJar.getFileName() + " → " + targetJar));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback: vanilla version jar (obfuscated names, may cause module issues)
|
System.out.println(ZAnsi.yellow(" No vanilla jar found at " + vanillaJar));
|
||||||
Path sourceJar = versionsDir.resolve(mcVersion).resolve(mcVersion + ".jar");
|
|
||||||
if (!Files.exists(sourceJar) || !isValidJar(sourceJar)) {
|
|
||||||
System.out.println(ZAnsi.yellow(" No suitable version jar found (SRG or vanilla)"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Files.copy(sourceJar, targetJar);
|
|
||||||
System.out.println(ZAnsi.yellow(" Copied vanilla jar (fallback) for securejarhandler: " + sourceJar.getFileName() + " → " + targetJar));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user