From 5e864b1e2d7c7463e105fb621621c18d1d17b296 Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Mon, 24 Jun 2024 13:49:11 +0200 Subject: [PATCH] Allow multiple copies of a class on the CP and pick the JAR containing the first. --- .../net/neoforged/fml/util/DevEnvUtils.java | 18 +++++++++++++++--- loader/src/main/resources/lang/en_us.json | 1 - 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/loader/src/main/java/net/neoforged/fml/util/DevEnvUtils.java b/loader/src/main/java/net/neoforged/fml/util/DevEnvUtils.java index 9c3341c4c..0af0c1cd2 100644 --- a/loader/src/main/java/net/neoforged/fml/util/DevEnvUtils.java +++ b/loader/src/main/java/net/neoforged/fml/util/DevEnvUtils.java @@ -13,13 +13,19 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import net.neoforged.fml.ModLoadingException; import net.neoforged.fml.ModLoadingIssue; import org.jetbrains.annotations.ApiStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @ApiStatus.Internal public final class DevEnvUtils { + private static final Logger LOG = LoggerFactory.getLogger(DevEnvUtils.class); + private DevEnvUtils() {} public static List findFileSystemRootsOfFileOnClasspath(String relativePath) { @@ -37,7 +43,8 @@ public static List findFileSystemRootsOfFileOnClasspath(String relativePat throw new IllegalArgumentException("Failed to enumerate classpath locations of " + relativePath); } - List result = new ArrayList<>(); + // Remove duplicates, but maintain order! + Set result = new LinkedHashSet<>(); while (resourceIt.hasNext()) { var resourceUrl = resourceIt.next(); @@ -66,7 +73,7 @@ public static List findFileSystemRootsOfFileOnClasspath(String relativePat } } - return result; + return new ArrayList<>(result); } public static Path findFileSystemRootOfFileOnClasspath(String relativePath) { @@ -75,7 +82,12 @@ public static Path findFileSystemRootOfFileOnClasspath(String relativePath) { if (paths.isEmpty()) { throw new ModLoadingException(ModLoadingIssue.error("fml.modloadingissue.failed_to_find_on_classpath", relativePath)); } else if (paths.size() > 1) { - throw new ModLoadingException(ModLoadingIssue.error("fml.modloadingissue.multiple_copies_on_classpath", relativePath, paths)); + // Warn for anything past the first. It's impossible to know if the user actually intended this setup, + // but to allow launching in uncommon configurations, we'll allow it. + for (int i = 1; i < paths.size(); i++) { + var path = paths.get(i); + LOG.warn("Found multiple copies of {} on classpath. Ignoring copy from {}, using {} instead.", relativePath, path, paths.getFirst()); + } } return paths.getFirst(); diff --git a/loader/src/main/resources/lang/en_us.json b/loader/src/main/resources/lang/en_us.json index f41315c1a..9d53c00c5 100644 --- a/loader/src/main/resources/lang/en_us.json +++ b/loader/src/main/resources/lang/en_us.json @@ -41,7 +41,6 @@ "fml.modloadingissue.maven_coordinate_not_found": "No mod with the Maven coordinate {0} could be found in {1}", "fml.modloadingissue.failed_to_list_folder_content": "Failed to list content of folder {0}", "fml.modloadingissue.failed_to_find_on_classpath": "Failed to find {0} on the classpath", - "fml.modloadingissue.multiple_copies_on_classpath": "Found multiple copies of {0} on the classpath: {1}", "fml.messages.artifactversion.ornotinstalled": "{0,ornull,fml.messages.artifactversion.notinstalled}", "fml.messages.artifactversion": "{0,ornull,fml.messages.artifactversion.none}", "fml.messages.artifactversion.none": "none",