Fix 11: Remove forge- from ignoreList, let forge client jar create minecraft module
Instead of copying the vanilla jar to versions/<versionId>/ and adding it to -cp (Fix 9/10), we now simply remove forge- from the -DignoreList pattern. This allows securejarhandler to process forge-1.20.1-47.4.20-client.jar on the classpath, which has Automatic-Module-Name: minecraft in its MANIFEST, and create the minecraft module from it. The forge client jar contains all patched MC classes, so PreparableReloadListener and all other vanilla classes are accessible in the minecraft module. No duplicate module creation, no split-package errors.
This commit is contained in:
+30
-29
@@ -63,18 +63,12 @@ public class LaunchCommandBuilder {
|
|||||||
// always use ModLauncher as main class (version.json might have
|
// always use ModLauncher as main class (version.json might have
|
||||||
// BootstrapLauncher which breaks with Java module system)
|
// BootstrapLauncher which breaks with Java module system)
|
||||||
if ("forge".equals(loaderType) || "neoforge".equals(loaderType)) {
|
if ("forge".equals(loaderType) || "neoforge".equals(loaderType)) {
|
||||||
// Ensure securejarhandler can create the "minecraft" module.
|
// Build classpath from manifest libraries only.
|
||||||
// The Forge installer only creates versions/<versionId>/<versionId>.json,
|
// The forge client jar (forge-*-client.jar) on the classpath
|
||||||
// NOT the jar. We copy the vanilla version jar there so
|
// contains the patched Minecraft classes and has
|
||||||
// securejarhandler finds it and creates the "minecraft" module.
|
// Automatic-Module-Name: minecraft in its MANIFEST.
|
||||||
ensureVersionJarForForge();
|
// We modify the ignoreList below to NOT exclude it,
|
||||||
|
// so securejarhandler creates the "minecraft" module from it.
|
||||||
// Build classpath from manifest libraries + the copied version jar.
|
|
||||||
// The copied jar (e.g. 1.20.1-forge-47.4.20.jar) does NOT match the
|
|
||||||
// "-DignoreList" pattern "forge-" (it starts with "1", not "forge-"),
|
|
||||||
// so securejarhandler will include it in the module layer.
|
|
||||||
// It also won't create automatic module "_1._20._1" because the
|
|
||||||
// filename is "1.20.1-forge-47.4.20.jar", not "1.20.1.jar".
|
|
||||||
String classpath;
|
String classpath;
|
||||||
if (manifest != null) {
|
if (manifest != null) {
|
||||||
classpath = buildClasspathFromManifest(manifest, false);
|
classpath = buildClasspathFromManifest(manifest, false);
|
||||||
@@ -85,31 +79,38 @@ public class LaunchCommandBuilder {
|
|||||||
classpath = buildVanillaClasspath();
|
classpath = buildVanillaClasspath();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the copied version jar to classpath (if it exists).
|
|
||||||
// securejarhandler scans classpath JARs and creates modules.
|
|
||||||
// The jar name "1.20.1-forge-47.4.20.jar" is NOT in ignoreList,
|
|
||||||
// so it becomes a proper module with Automatic-Module-Name: minecraft.
|
|
||||||
Path copiedVersionJar = instance.getPath().resolve("versions")
|
|
||||||
.resolve(getVersionId()).resolve(getVersionId() + ".jar");
|
|
||||||
if (Files.exists(copiedVersionJar) && isValidJar(copiedVersionJar)) {
|
|
||||||
String sep = System.getProperty("os.name").toLowerCase().contains("win") ? ";" : ":";
|
|
||||||
classpath = copiedVersionJar.toAbsolutePath().toString() + sep + classpath;
|
|
||||||
System.out.println(ZAnsi.green(" Added version jar for minecraft module: " + copiedVersionJar.getFileName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
command.add("-cp");
|
command.add("-cp");
|
||||||
String cpFile = writeClasspathFile(classpath);
|
String cpFile = writeClasspathFile(classpath);
|
||||||
command.add(cpFile);
|
command.add(cpFile);
|
||||||
|
|
||||||
// Add JVM arguments from version.json manifest as-is.
|
// Add JVM arguments from version.json manifest.
|
||||||
// Forge's -p is a HARDCODED list of 8 bootstrap JARs (bootstraplauncher,
|
// Forge's -p is a HARDCODED list of 8 bootstrap JARs
|
||||||
// securejarhandler, asm-*, JarJarFileSystems) — NOT ${classpath}.
|
// (bootstraplauncher, securejarhandler, asm-*, JarJarFileSystems).
|
||||||
// Do NOT intercept it.
|
// Intercept -DignoreList to remove "forge-" pattern, which
|
||||||
|
// blocks the forge client jar (forge-*-client.jar) from being
|
||||||
|
// processed by securejarhandler into the "minecraft" module.
|
||||||
if (manifest != null) {
|
if (manifest != null) {
|
||||||
Map<String, String> vars = buildVariableMap(options);
|
Map<String, String> vars = buildVariableMap(options);
|
||||||
vars.put("classpath", cpFile);
|
vars.put("classpath", cpFile);
|
||||||
for (String arg : manifest.getJvmArguments()) {
|
for (String arg : manifest.getJvmArguments()) {
|
||||||
command.add(resolveVariable(arg, vars));
|
String resolved = resolveVariable(arg, vars);
|
||||||
|
if (resolved.startsWith("-DignoreList=")) {
|
||||||
|
String value = resolved.substring("-DignoreList=".length());
|
||||||
|
// Remove forge- from the comma-separated list:
|
||||||
|
// - ,forge-, in the middle → just the comma
|
||||||
|
// - ,forge- at the end → remove
|
||||||
|
// - forge-, at the start → remove
|
||||||
|
String modified = value
|
||||||
|
.replace(",forge-,", ",")
|
||||||
|
.replace(",forge-", "")
|
||||||
|
.replace("forge-,", "");
|
||||||
|
if (modified.equals("forge-")) modified = "";
|
||||||
|
if (!modified.equals(value)) {
|
||||||
|
System.out.println(ZAnsi.green(" Removed 'forge-' from ignoreList"));
|
||||||
|
}
|
||||||
|
resolved = "-DignoreList=" + modified;
|
||||||
|
}
|
||||||
|
command.add(resolved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user