diff --git a/subprojects/base-services/src/main/java/org/gradle/internal/exceptions/DefaultMultiCauseException.java b/subprojects/base-services/src/main/java/org/gradle/internal/exceptions/DefaultMultiCauseException.java index 1535ce97d96e..b97172eea4a0 100644 --- a/subprojects/base-services/src/main/java/org/gradle/internal/exceptions/DefaultMultiCauseException.java +++ b/subprojects/base-services/src/main/java/org/gradle/internal/exceptions/DefaultMultiCauseException.java @@ -74,12 +74,14 @@ private void writeObject(java.io.ObjectOutputStream out) throws IOException { } private ThreadLocal threadLocal() { - return new ThreadLocal() { - @Override - protected Boolean initialValue() { - return false; - } - }; + return new HideStacktrace(); + } + + private static class HideStacktrace extends ThreadLocal { + @Override + protected Boolean initialValue() { + return false; + } } @Override diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/DefaultMutationGuard.java b/subprojects/core/src/main/java/org/gradle/api/internal/DefaultMutationGuard.java index c6e0a4804b7c..d512e31cc4a6 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/DefaultMutationGuard.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/DefaultMutationGuard.java @@ -19,12 +19,13 @@ import org.gradle.api.Action; public class DefaultMutationGuard extends AbstractMutationGuard { - private final ThreadLocal mutationGuardState = new ThreadLocal() { + private final ThreadLocal mutationGuardState = new GuardState(); + private static class GuardState extends ThreadLocal { @Override protected Boolean initialValue() { return Boolean.TRUE; } - }; + } @Override public boolean isMutationAllowed() { diff --git a/subprojects/dependency-management/src/main/java/org/gradle/internal/resolve/resolver/DefaultArtifactSelector.java b/subprojects/dependency-management/src/main/java/org/gradle/internal/resolve/resolver/DefaultArtifactSelector.java index 3e0adfb57856..2e2bcba578b8 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/internal/resolve/resolver/DefaultArtifactSelector.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/internal/resolve/resolver/DefaultArtifactSelector.java @@ -67,9 +67,11 @@ public ArtifactSet resolveArtifacts(LocalFileDependencyMetadata fileDependencyMe @Override public ArtifactSet resolveArtifacts(ComponentResolveMetadata component, @Nullable Map resolvedVariantCache, Supplier> allVariants, Set legacyVariants, ExcludeSpec exclusions, ImmutableAttributes overriddenAttributes) { + ModuleVersionIdentifier moduleVersionId = component.getModuleVersionId(); + ModuleSources sources = component.getSources(); - ImmutableSet legacyResolvedVariants = buildResolvedVariants(component, legacyVariants, exclusions, resolvedVariantCache); - ComponentArtifactResolveVariantState componentArtifactResolveVariantState = () -> buildResolvedVariants(component, allVariants.get(), exclusions, resolvedVariantCache); + ImmutableSet legacyResolvedVariants = buildResolvedVariants(moduleVersionId, sources, legacyVariants, exclusions, resolvedVariantCache); + ComponentArtifactResolveVariantState componentArtifactResolveVariantState = () -> buildResolvedVariants(moduleVersionId, sources, allVariants.get(), exclusions, resolvedVariantCache); for (OriginArtifactSelector selector : selectors) { ArtifactSet artifacts = selector.resolveArtifacts(component, componentArtifactResolveVariantState, legacyResolvedVariants, exclusions, overriddenAttributes); @@ -80,10 +82,10 @@ public ArtifactSet resolveArtifacts(ComponentResolveMetadata component, @Nullabl throw new IllegalStateException("No artifacts selected."); } - private ImmutableSet buildResolvedVariants(ComponentResolveMetadata component, Set allVariants, ExcludeSpec exclusions, @Nullable Map resolvedVariantCache) { + private ImmutableSet buildResolvedVariants(ModuleVersionIdentifier moduleVersionId, ModuleSources sources, Set allVariants, ExcludeSpec exclusions, @Nullable Map resolvedVariantCache) { ImmutableSet.Builder resolvedVariantBuilder = ImmutableSet.builder(); for (VariantResolveMetadata variant : allVariants) { - ResolvedVariant resolvedVariant = toResolvedVariant(variant.getIdentifier(), variant.asDescribable(), variant.getAttributes(), variant.getArtifacts(), variant.getCapabilities(), exclusions, component.getModuleVersionId(), component.getSources(), resolvedVariantCache); + ResolvedVariant resolvedVariant = toResolvedVariant(variant.getIdentifier(), variant.asDescribable(), variant.getAttributes(), variant.getArtifacts(), variant.getCapabilities(), exclusions, moduleVersionId, sources, resolvedVariantCache); resolvedVariantBuilder.add(resolvedVariant); } return resolvedVariantBuilder.build(); diff --git a/subprojects/docs/src/docs/userguide/migration/upgrading_version_7.adoc b/subprojects/docs/src/docs/userguide/migration/upgrading_version_7.adoc index 527b53c19cfb..2bbfeb296d6e 100644 --- a/subprojects/docs/src/docs/userguide/migration/upgrading_version_7.adoc +++ b/subprojects/docs/src/docs/userguide/migration/upgrading_version_7.adoc @@ -673,7 +673,7 @@ tasks.withType().configureEach { Groovy has been updated to https://groovy-lang.org/changelogs/changelog-3.0.13.html[Groovy 3.0.13]. -Since the previous version was 3.0.11, the https://groovy-lang.org/changelogs/changelog-3.0.12.html[3.0.12 changes] are also included. +Since the previous version was 3.0.10, the https://groovy-lang.org/changelogs/changelog-3.0.11.html[3.0.11] and https://groovy-lang.org/changelogs/changelog-3.0.12.html[3.0.12] changes are also included. ==== Upgrade to CodeNarc 3.1.0 @@ -1151,6 +1151,7 @@ The same is true for `link:{javadocPath}/org/gradle/api/tasks/TaskInputs.html#di ==== Using LazyPublishArtifact without a FileResolver is deprecated When using a LazyPublishArtifact without a FileResolver, a different file resolution strategy is used, which duplicates some logic in the FileResolver. + To improve consistency, LazyPublishArtifact should be used with a FileResolver, and will require it in the future. This also affects other internal APIs that use LazyPublishArtifact, which now also have deprecation warnings where needed. @@ -1169,6 +1170,7 @@ This way, Gradle is able to apply optimizations like up-to-date checks instead o ==== Unique attribute sets The set of link:{javadocPath}/org/gradle/api/attributes/Attribute.html[Attribute]s associated with a _consumable_ configuration within a project, must be unique across all other configurations within that project which share the same set of link:{javadocPath}/org/gradle/api/capabilities/Capability.html[Capability]s. + This will be checked at the end of configuring variant configurations, as they are locked against further mutation. If the set of attributes is shared across configurations, consider adding an additional attribute to one of the variants for the sole purpose of disambiguation. @@ -1275,6 +1277,7 @@ These methods were changed to improve the consistency between the `libs.versions ==== Application order of plugins in the `plugins` block The order in which plugins in the `plugins` block were actually applied was inconsistent and depended on how a plugin was added to the class path. + Now the plugins are always applied in the same order they are declared in the `plugins` block which in rare cases might change behavior of existing builds. ==== Effects of exclusion on substituted dependencies in dependency resolution diff --git a/subprojects/jvm-services/src/main/java/org/gradle/jvm/toolchain/internal/JavaInstallationRegistry.java b/subprojects/jvm-services/src/main/java/org/gradle/jvm/toolchain/internal/JavaInstallationRegistry.java index 9da3ab4fd00f..a541a2e1ea85 100644 --- a/subprojects/jvm-services/src/main/java/org/gradle/jvm/toolchain/internal/JavaInstallationRegistry.java +++ b/subprojects/jvm-services/src/main/java/org/gradle/jvm/toolchain/internal/JavaInstallationRegistry.java @@ -17,7 +17,6 @@ package org.gradle.jvm.toolchain.internal; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Supplier; import org.gradle.api.GradleException; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; @@ -36,6 +35,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Collectors; @@ -151,12 +151,12 @@ public BuildOperationDescriptor.Builder description() { private static class Installations { - private final Supplier> initialiser; + private final Supplier> initializer; private Set locations = null; - Installations(Supplier> initialiser) { - this.initialiser = initialiser; + Installations(Supplier> initializer) { + this.initializer = initializer; } synchronized Set get() { @@ -171,7 +171,7 @@ synchronized void add(InstallationLocation location) { private void initIfNeeded() { if (locations == null) { - locations = initialiser.get(); + locations = initializer.get(); } } diff --git a/subprojects/model-core/src/integTest/groovy/org/gradle/internal/extensibility/CallablePropertyIntegrationTest.groovy b/subprojects/model-core/src/integTest/groovy/org/gradle/internal/extensibility/CallablePropertyIntegrationTest.groovy index e5a53c463632..552e4ad5ef4b 100644 --- a/subprojects/model-core/src/integTest/groovy/org/gradle/internal/extensibility/CallablePropertyIntegrationTest.groovy +++ b/subprojects/model-core/src/integTest/groovy/org/gradle/internal/extensibility/CallablePropertyIntegrationTest.groovy @@ -18,6 +18,7 @@ package org.gradle.internal.extensibility import org.gradle.integtests.fixtures.AbstractIntegrationSpec +import spock.lang.Issue class CallablePropertyIntegrationTest extends AbstractIntegrationSpec { @@ -95,4 +96,19 @@ class CallablePropertyIntegrationTest extends AbstractIntegrationSpec { "Inside Project.configure" | "configure(container.foo) { prop() }" "Inside NDOC.configure" | "container.configure { foo { prop() } }" } + + @Issue('https://github.com/gradle/gradle/issues/23111') + def "can configure dynamic property without call method"() { + buildFile << """ + task test { + doLast { + ant { echo(message: 'hello world!') } + } + } + """ + + expect: + args('--stacktrace') + succeeds("test") + } } diff --git a/subprojects/model-core/src/main/java/org/gradle/internal/extensibility/MixInClosurePropertiesAsMethodsDynamicObject.java b/subprojects/model-core/src/main/java/org/gradle/internal/extensibility/MixInClosurePropertiesAsMethodsDynamicObject.java index a58375206b7c..4ba1f999c477 100644 --- a/subprojects/model-core/src/main/java/org/gradle/internal/extensibility/MixInClosurePropertiesAsMethodsDynamicObject.java +++ b/subprojects/model-core/src/main/java/org/gradle/internal/extensibility/MixInClosurePropertiesAsMethodsDynamicObject.java @@ -56,7 +56,9 @@ public DynamicInvokeResult tryInvokeMethod(String name, Object... arguments) { return DynamicInvokeResult.found(); } DynamicObject dynamicObject = DynamicObjectUtil.asDynamicObject(property); - return dynamicObject.tryInvokeMethod("call", arguments); + if (dynamicObject.hasMethod("call", arguments)) { + return dynamicObject.tryInvokeMethod("call", arguments); + } } return DynamicInvokeResult.notFound(); } diff --git a/subprojects/model-core/src/main/java/org/gradle/model/internal/registry/RuleContext.java b/subprojects/model-core/src/main/java/org/gradle/model/internal/registry/RuleContext.java index ada40864a8a1..2281dd8308cb 100644 --- a/subprojects/model-core/src/main/java/org/gradle/model/internal/registry/RuleContext.java +++ b/subprojects/model-core/src/main/java/org/gradle/model/internal/registry/RuleContext.java @@ -24,12 +24,7 @@ public class RuleContext { - private static final ThreadLocal> STACK = new ThreadLocal>() { - @Override - protected Deque initialValue() { - return new ArrayDeque(); - } - }; + private static final ThreadLocal> STACK = ThreadLocal.withInitial(ArrayDeque::new); @Nullable public static ModelRuleDescriptor get() {