From b5f79ef8f64fc11d13f40ee4877b7202f88c3741 Mon Sep 17 00:00:00 2001 From: modmuss Date: Thu, 25 Sep 2025 19:47:25 +0100 Subject: [PATCH] Update Gradle test versions (#1370) * Update Gradle test versions * 9.3 nightly's * Don't ask. * Fix another test --- gradle/test.libs.versions.toml | 4 +-- .../configuration/CompileConfiguration.java | 26 ++++++++++++++++--- .../integration/MultiMcVersionTest.groovy | 5 ++-- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/gradle/test.libs.versions.toml b/gradle/test.libs.versions.toml index 77f61566..7e88ca44 100644 --- a/gradle/test.libs.versions.toml +++ b/gradle/test.libs.versions.toml @@ -7,8 +7,8 @@ java-debug = "0.53.1" mixin = "0.15.3+mixin.0.8.7" bouncycastle = "1.81" -gradle-latest = "9.0.0" -gradle-nightly = "9.2.0-20250902075334+0000" +gradle-latest = "9.1.0" +gradle-nightly = "9.3.0-20250923005153+0000" fabric-loader = "0.16.14" [libraries] diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index b889a68f..6c050bd0 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -33,6 +33,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.time.Duration; +import java.util.Objects; import java.util.Optional; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -80,6 +81,8 @@ import net.fabricmc.loom.util.service.ScopedServiceFactory; import net.fabricmc.loom.util.service.ServiceFactory; public abstract class CompileConfiguration implements Runnable { + private static final String LOCK_PROPERTY_KEY = "fabric.loom.internal.global.lock"; + @Inject protected abstract Project getProject(); @@ -110,7 +113,11 @@ public abstract class CompileConfiguration implements Runnable { } try { - setupMinecraft(configContext); + // Setting up loom across Gradle projects is not thread safe, synchronize it here to ensure that multiple projects cannot use it. + // There is no easy way around this, as we want to use the same global cache for downloaded or generated files. + synchronized (getGlobalLockObject()) { + setupMinecraft(configContext); + } LoomDependencyManager dependencyManager = new LoomDependencyManager(); extension.setDependencyManager(dependencyManager); @@ -151,8 +158,7 @@ public abstract class CompileConfiguration implements Runnable { } } - // This is not thread safe across getProject()s synchronize it here just to be sure, might be possible to move this further down, but for now this will do. - private synchronized void setupMinecraft(ConfigContext configContext) throws Exception { + private void setupMinecraft(ConfigContext configContext) throws Exception { final Project project = configContext.project(); final LoomGradleExtension extension = configContext.extension(); @@ -457,4 +463,18 @@ public abstract class CompileConfiguration implements Runnable { } }); } + + // This is a nasty piece of work, but seems to work quite nicely. + // We need a lock that works across classloaders, a regular synchronized method will not work here. + // We can abuse system properties as a shared object store that we know for sure will be on the same classloader regardless of what Gradle does to loom. + // This allows us to ensure that all instances of loom regardless of classloader get the same object to lock on. + private static Object getGlobalLockObject() { + if (!System.getProperties().contains(LOCK_PROPERTY_KEY)) { + // The .intern resolves a possible race where two difference value objects (remember not the same classloader) are set. + //noinspection StringOperationCanBeSimplified + System.getProperties().setProperty(LOCK_PROPERTY_KEY, LOCK_PROPERTY_KEY.intern()); + } + + return Objects.requireNonNull(System.getProperty(LOCK_PROPERTY_KEY)); + } } diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/MultiMcVersionTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/MultiMcVersionTest.groovy index 3c8d531b..14ccba0d 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/MultiMcVersionTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/MultiMcVersionTest.groovy @@ -29,6 +29,7 @@ import spock.lang.Unroll import net.fabricmc.loom.test.util.GradleProjectTestTrait +import static net.fabricmc.loom.test.LoomTestConstants.PRE_RELEASE_GRADLE import static net.fabricmc.loom.test.LoomTestConstants.STANDARD_TEST_VERSIONS import static org.gradle.testkit.runner.TaskOutcome.SUCCESS @@ -89,7 +90,7 @@ class MultiMcVersionTest extends Specification implements GradleProjectTestTrait // See: https://github.com/gradle/gradle/issues/30401 // By default parallel configuration of all projects is preferred. args: [ - "-Dorg.gradle.internal.isolated-projects.configure-on-demand.tasks=true" + "-Dorg.gradle.internal.isolated-projects.configure-on-demand=true" ]) then: @@ -98,6 +99,6 @@ class MultiMcVersionTest extends Specification implements GradleProjectTestTrait result.output.count("Fabric Loom:") == 1 where: - version << STANDARD_TEST_VERSIONS + version << [PRE_RELEASE_GRADLE] } }