From bab1aa82163806b4a4a8172d8c40443c82c1cafc Mon Sep 17 00:00:00 2001
From: Juuxel <6596629+Juuxel@users.noreply.github.com>
Date: Tue, 17 May 2022 23:35:38 +0300
Subject: [PATCH 1/2] Expose underlying messages in RemapJarTask and Minecraft
setup (#650)
Closes #649. Closes #638.
---
.../configuration/CompileConfiguration.java | 3 +-
.../net/fabricmc/loom/task/RemapJarTask.java | 3 +-
.../net/fabricmc/loom/util/ExceptionUtil.java | 47 +++++++++++++++++++
3 files changed, 51 insertions(+), 2 deletions(-)
create mode 100644 src/main/java/net/fabricmc/loom/util/ExceptionUtil.java
diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java
index 68c05d1f..d03cfda3 100644
--- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java
+++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java
@@ -55,6 +55,7 @@ import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMi
import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider;
import net.fabricmc.loom.extension.MixinExtension;
import net.fabricmc.loom.util.Constants;
+import net.fabricmc.loom.util.ExceptionUtil;
public final class CompileConfiguration {
private CompileConfiguration() {
@@ -147,7 +148,7 @@ public final class CompileConfiguration {
try {
setupMinecraft(project);
} catch (Exception e) {
- throw new RuntimeException("Failed to setup minecraft", e);
+ throw ExceptionUtil.createDescriptiveWrapper(RuntimeException::new, "Failed to setup Minecraft", e);
}
LoomDependencyManager dependencyManager = new LoomDependencyManager();
diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java
index 300e1c22..fe1e53b4 100644
--- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java
+++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java
@@ -75,6 +75,7 @@ import net.fabricmc.loom.extension.MixinExtension;
import net.fabricmc.loom.task.service.JarManifestService;
import net.fabricmc.loom.task.service.TinyRemapperService;
import net.fabricmc.loom.util.Constants;
+import net.fabricmc.loom.util.ExceptionUtil;
import net.fabricmc.loom.util.Pair;
import net.fabricmc.loom.util.SidedClassVisitor;
import net.fabricmc.loom.util.ZipUtils;
@@ -241,7 +242,7 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
LOGGER.error("Failed to delete output file", ex);
}
- throw new RuntimeException("Failed to remap", e);
+ throw ExceptionUtil.createDescriptiveWrapper(RuntimeException::new, "Failed to remap", e);
}
}
diff --git a/src/main/java/net/fabricmc/loom/util/ExceptionUtil.java b/src/main/java/net/fabricmc/loom/util/ExceptionUtil.java
new file mode 100644
index 00000000..3683301e
--- /dev/null
+++ b/src/main/java/net/fabricmc/loom/util/ExceptionUtil.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of fabric-loom, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) 2022 FabricMC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.fabricmc.loom.util;
+
+import java.util.function.BiFunction;
+
+public final class ExceptionUtil {
+ /**
+ * Creates a descriptive user-facing wrapper exception for an underlying cause.
+ *
+ *
The output format has a message like this: {@code [message], [cause class]: [cause message]}.
+ * For example: {@code Failed to remap, java.io.IOException: Access denied}.
+ *
+ * @param constructor the exception factory which takes in a message and a cause
+ * @param message the more general message for the resulting exception
+ * @param cause the causing exception
+ * @param the created exception type
+ * @param the cause type
+ * @return the created exception
+ */
+ public static E createDescriptiveWrapper(BiFunction constructor, String message, C cause) {
+ String descriptiveMessage = "%s, %s: %s".formatted(message, cause.getClass().getName(), cause.getMessage());
+ return constructor.apply(descriptiveMessage, cause);
+ }
+}
From b8687c87ceb49b37a4e92ef30826cf1d000fd73e Mon Sep 17 00:00:00 2001
From: modmuss50
Date: Wed, 18 May 2022 18:27:11 +0100
Subject: [PATCH 2/2] Support 1.19-pre1, natives are now all loaded via the
classpath.
---
.../configuration/CompileConfiguration.java | 1 -
.../minecraft/MinecraftLibraryProvider.java | 15 ++++++++++
.../minecraft/MinecraftVersionMeta.java | 17 +++++++----
.../net/fabricmc/loom/task/LoomTasks.java | 4 ---
.../task/launch/GenerateDLIConfigTask.java | 13 ++++----
.../net/fabricmc/loom/util/Constants.java | 3 ++
.../loom/test/integration/NativesTest.groovy | 30 +++++++++++++++++++
7 files changed, 68 insertions(+), 15 deletions(-)
diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java
index d03cfda3..a08e8262 100644
--- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java
+++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java
@@ -72,7 +72,6 @@ public final class CompileConfiguration {
configuration.extendsFrom(serverDeps.get());
configuration.setTransitive(false);
});
- extension.createLazyConfiguration(Constants.Configurations.MINECRAFT_NATIVES, configuration -> configuration.setTransitive(false));
extension.createLazyConfiguration(Constants.Configurations.LOADER_DEPENDENCIES, configuration -> configuration.setTransitive(false));
extension.createLazyConfiguration(Constants.Configurations.MINECRAFT, configuration -> configuration.setTransitive(false));
extension.createLazyConfiguration(Constants.Configurations.INCLUDE, configuration -> configuration.setTransitive(false)); // Dont get transitive deps
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java
index 260ec81f..b82ca2dc 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftLibraryProvider.java
@@ -29,10 +29,13 @@ import java.util.regex.Pattern;
import org.gradle.api.Project;
import org.gradle.api.artifacts.ExternalModuleDependency;
+import org.gradle.api.tasks.TaskContainer;
+import org.gradle.api.tasks.TaskProvider;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.LoomRepositoryPlugin;
import net.fabricmc.loom.configuration.providers.BundleMetadata;
+import net.fabricmc.loom.task.ExtractNativesTask;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.OperatingSystem;
@@ -53,6 +56,18 @@ public class MinecraftLibraryProvider {
project.getLogger().warn("Loom is upgrading Minecraft's LWJGL version to {}", LWJGLVersionOverride.LWJGL_VERSION);
}
+ if (versionInfo.hasNativesToExtract()) {
+ final TaskContainer tasks = project.getTasks();
+
+ extension.createLazyConfiguration(Constants.Configurations.MINECRAFT_NATIVES, configuration -> configuration.setTransitive(false));
+
+ TaskProvider extractNativesTask = tasks.register("extractNatives", ExtractNativesTask.class, t -> {
+ t.setDescription("Extracts the minecraft platform specific natives.");
+ });
+
+ tasks.named("configureClientLaunch", configureClientLaunch -> configureClientLaunch.dependsOn(extractNativesTask));
+ }
+
for (MinecraftVersionMeta.Library library : versionInfo.libraries()) {
if (overrideLWJGL && library.name().startsWith("org.lwjgl")) {
continue;
diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftVersionMeta.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftVersionMeta.java
index 26612d49..6e38296f 100644
--- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftVersionMeta.java
+++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftVersionMeta.java
@@ -56,6 +56,10 @@ public record MinecraftVersionMeta(
return this.releaseTime().compareTo(releaseTime) >= 0;
}
+ public boolean hasNativesToExtract() {
+ return libraries.stream().anyMatch(Library::hasNatives);
+ }
+
public record AssetIndex(String id, long totalSize, String path, String sha1, long size, String url) {
public String fabricId(String version) {
return id.equals(version) ? version : version + "-" + id;
@@ -64,17 +68,20 @@ public record MinecraftVersionMeta(
public record Library(Downloads downloads, String name, Map natives, List rules, Object extract) {
public boolean isValidForOS() {
- if (rules == null || rules.isEmpty()) {
+ if (rules == null) {
+ // No rules allow everything.
return true;
}
- for (Rule rule : rules) {
- if (rule.appliesToOS() && !rule.isAllowed()) {
- return false;
+ boolean valid = false;
+
+ for (Rule rule : this.rules) {
+ if (rule.appliesToOS()) {
+ valid = rule.isAllowed();
}
}
- return true;
+ return valid;
}
public boolean hasNatives() {
diff --git a/src/main/java/net/fabricmc/loom/task/LoomTasks.java b/src/main/java/net/fabricmc/loom/task/LoomTasks.java
index 78163b24..7ec675af 100644
--- a/src/main/java/net/fabricmc/loom/task/LoomTasks.java
+++ b/src/main/java/net/fabricmc/loom/task/LoomTasks.java
@@ -54,9 +54,6 @@ public final class LoomTasks {
RemapTaskConfiguration.setupRemap(project);
- tasks.register("extractNatives", ExtractNativesTask.class, t -> {
- t.setDescription("Extracts the minecraft platform specific natives.");
- });
tasks.register("downloadAssets", DownloadAssetsTask.class, t -> {
t.setDescription("Downloads required assets for Fabric.");
});
@@ -80,7 +77,6 @@ public final class LoomTasks {
});
tasks.register("configureClientLaunch", task -> {
- task.dependsOn(tasks.named("extractNatives"));
task.dependsOn(tasks.named("downloadAssets"));
task.dependsOn(tasks.named("configureLaunch"));
diff --git a/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java b/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java
index 3e078131..49a6b1c1 100644
--- a/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java
+++ b/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java
@@ -47,8 +47,6 @@ import net.fabricmc.loom.util.gradle.SourceSetHelper;
public abstract class GenerateDLIConfigTask extends AbstractLoomTask {
@TaskAction
public void run() throws IOException {
- final String nativesPath = getExtension().getFiles().getNativesDirectory(getProject()).getAbsolutePath();
-
final MinecraftVersionMeta versionInfo = getExtension().getMinecraftProvider().getVersionInfo();
File assetsDirectory = new File(getExtension().getFiles().getUserCache(), "assets");
@@ -62,14 +60,19 @@ public abstract class GenerateDLIConfigTask extends AbstractLoomTask {
.property("log4j.configurationFile", getAllLog4JConfigFiles())
.property("log4j2.formatMsgNoLookups", "true")
- .property("client", "java.library.path", nativesPath)
- .property("client", "org.lwjgl.librarypath", nativesPath)
-
.argument("client", "--assetIndex")
.argument("client", getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().minecraftVersion()))
.argument("client", "--assetsDir")
.argument("client", assetsDirectory.getAbsolutePath());
+ if (versionInfo.hasNativesToExtract()) {
+ String nativesPath = getExtension().getFiles().getNativesDirectory(getProject()).getAbsolutePath();
+
+ launchConfig
+ .property("client", "java.library.path", nativesPath)
+ .property("client", "org.lwjgl.librarypath", nativesPath);
+ }
+
if (getExtension().areEnvironmentSourceSetsSplit()) {
launchConfig.property("client", "fabric.gameJarPath.client", getGameJarPath("client"));
launchConfig.property("fabric.gameJarPath", getGameJarPath("common"));
diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java
index c6417c90..87c977e5 100644
--- a/src/main/java/net/fabricmc/loom/util/Constants.java
+++ b/src/main/java/net/fabricmc/loom/util/Constants.java
@@ -69,6 +69,9 @@ public class Constants {
public static final String MINECRAFT_SERVER_DEPENDENCIES = "minecraftServerLibraries";
public static final String MINECRAFT_DEPENDENCIES = "minecraftLibraries";
public static final String MINECRAFT_RUNTIME_DEPENDENCIES = "minecraftRuntimeOnlyLibraries";
+ /**
+ * Not used on Minecraft 1.19-pre1 or later. Natives are all loaded from the classpath.
+ */
public static final String MINECRAFT_NATIVES = "minecraftNatives";
public static final String MAPPINGS = "mappings";
public static final String MAPPINGS_FINAL = "mappingsFinal";
diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/NativesTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/NativesTest.groovy
index 76d5c438..a4e81f68 100644
--- a/src/test/groovy/net/fabricmc/loom/test/integration/NativesTest.groovy
+++ b/src/test/groovy/net/fabricmc/loom/test/integration/NativesTest.groovy
@@ -83,4 +83,34 @@ class NativesTest extends Specification implements GradleProjectTestTrait {
where:
version << STANDARD_TEST_VERSIONS
}
+
+ @RestoreSystemProperties
+ @Unroll
+ def "1.19 classpath natives (gradle #version)"() {
+ setup:
+ def gradle = gradleProject(project: "minimalBase", version: version)
+
+ gradle.buildGradle << '''
+ loom {
+ noIntermediateMappings()
+ }
+
+ dependencies {
+ minecraft "com.mojang:minecraft:1.19-pre1"
+ mappings loom.layered() {
+ // No names
+ }
+ }
+ '''
+
+ when:
+ // Run the task twice to ensure its up to date
+ def result = gradle.run(task: "build")
+
+ then:
+ result.task(":build").outcome == SUCCESS
+
+ where:
+ version << STANDARD_TEST_VERSIONS
+ }
}