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 + } }