From 85314dac39973a2ae2550a1b5aefb291b5baecc1 Mon Sep 17 00:00:00 2001 From: Justin Van Dort Date: Mon, 19 Dec 2022 16:26:57 -0500 Subject: [PATCH 1/3] Fix #23096 on release7x --- subprojects/base-services/build.gradle.kts | 1 + .../java/org/gradle/util/internal/GUtil.java | 2 + .../MinimalExternalModuleDependency.java | 6 + .../DependencyFactoryInternal.java | 1 + .../ArtifactDeclarationIntegrationTest.groovy | 60 ++++++++- .../artifacts/DefaultDependencyFactory.java | 5 +- .../DefaultExternalModuleDependency.java | 2 +- .../DefaultMinimalDependency.java | 8 +- .../DefaultMinimalDependencyVariant.java | 117 +++++++++++++----- .../DefaultMutableMinimalDependency.java | 8 +- ...nimalExternalModuleDependencyInternal.java | 23 ++++ .../DefaultDependencyHandler.java | 4 +- .../notations/DependencyNotationParser.java | 63 ++++++---- 13 files changed, 236 insertions(+), 64 deletions(-) create mode 100644 subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java diff --git a/subprojects/base-services/build.gradle.kts b/subprojects/base-services/build.gradle.kts index e8c828e796ea..4c408aabc608 100644 --- a/subprojects/base-services/build.gradle.kts +++ b/subprojects/base-services/build.gradle.kts @@ -24,6 +24,7 @@ tasks.named("jmhCompileGeneratedClasses") { moduleIdentity.createBuildReceipt() dependencies { + api(libs.jetbrainsAnnotations) api(project(":base-annotations")) api(project(":worker-services")) api(project(":hashing")) diff --git a/subprojects/base-services/src/main/java/org/gradle/util/internal/GUtil.java b/subprojects/base-services/src/main/java/org/gradle/util/internal/GUtil.java index 11e2938da254..77e62b2b632c 100644 --- a/subprojects/base-services/src/main/java/org/gradle/util/internal/GUtil.java +++ b/subprojects/base-services/src/main/java/org/gradle/util/internal/GUtil.java @@ -24,6 +24,7 @@ import org.gradle.internal.Factory; import org.gradle.internal.IoActions; import org.gradle.internal.UncheckedException; +import org.jetbrains.annotations.Contract; import javax.annotation.Nullable; import java.io.File; @@ -157,6 +158,7 @@ public static boolean isTrue(@Nullable Object object) { * would trigger early configuration. */ @Nullable + @Contract("!null, _ -> param1; null, !null -> param2; null, null -> null") public static T elvis(@Nullable T object, @Nullable T defaultValue) { return isTrue(object) ? object : defaultValue; } diff --git a/subprojects/core-api/src/main/java/org/gradle/api/artifacts/MinimalExternalModuleDependency.java b/subprojects/core-api/src/main/java/org/gradle/api/artifacts/MinimalExternalModuleDependency.java index f3566ef2fd6a..cf00aa8861ba 100644 --- a/subprojects/core-api/src/main/java/org/gradle/api/artifacts/MinimalExternalModuleDependency.java +++ b/subprojects/core-api/src/main/java/org/gradle/api/artifacts/MinimalExternalModuleDependency.java @@ -26,4 +26,10 @@ public interface MinimalExternalModuleDependency extends ExternalModuleDependency { ModuleIdentifier getModule(); VersionConstraint getVersionConstraint(); + + /** + * {@inheritDoc} + */ + @Override + MinimalExternalModuleDependency copy(); } diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DependencyFactoryInternal.java b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DependencyFactoryInternal.java index c4d942a7f418..6d8869455ae4 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DependencyFactoryInternal.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DependencyFactoryInternal.java @@ -47,4 +47,5 @@ enum ClassPathNotation { DependencyConstraint createDependencyConstraint(Object dependencyNotation); ClientModule createModule(Object dependencyNotation, Closure configureClosure); ProjectDependency createProjectDependencyFromMap(ProjectFinder projectFinder, Map map); + void injectServices(Dependency dependency); } diff --git a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy index ee7f681cdfe0..5f929a0eb83a 100644 --- a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy +++ b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy @@ -209,7 +209,7 @@ task checkArtifacts { } task jar {} } - + project(':b') { dependencies { compile project(':a') @@ -218,7 +218,7 @@ task checkArtifacts { task checkArtifacts { inputs.files configurations.compile doLast { - configurations.compile.resolvedConfiguration.resolvedArtifacts.forEach { println it } + configurations.compile.resolvedConfiguration.resolvedArtifacts.forEach { println it } } } } @@ -247,7 +247,7 @@ task checkArtifacts { } task jar {} } - + project(':b') { dependencies { compile project(':a') @@ -256,7 +256,7 @@ task checkArtifacts { task checkArtifacts { inputs.files configurations.compile doLast { - assert configurations.compile.resolvedConfiguration.resolvedArtifacts.each { println it } + assert configurations.compile.resolvedConfiguration.resolvedArtifacts.each { println it } } } } @@ -289,7 +289,7 @@ task checkArtifacts { } task classes {} } - + project(':b') { dependencies { compile project(':a') @@ -298,7 +298,7 @@ task checkArtifacts { task checkArtifacts { inputs.files configurations.compile doLast { - assert configurations.compile.resolvedConfiguration.resolvedArtifacts.each { println it } + assert configurations.compile.resolvedConfiguration.resolvedArtifacts.each { println it } } } } @@ -506,4 +506,52 @@ task checkArtifacts { result.assertTasksExecutedInOrder(":a:checkArtifacts", ":a:jar", ":b:checkArtifacts") } + def 'artifacts are copied when declaring dependency on existing version catalog dependency with artifact'() { + given: + buildFile << """ + configurations { + implementation + destination1 + destination2 + } + + dependencies { + implementation(libs.test) { + artifact { + classifier = "alternative" + } + } + } + + task copyAndPrintDependencies { + doLast { + configurations.implementation.dependencies.each { + project.dependencies.add("destination1", it) + configurations.destination2.dependencies.add(it) + } + configurations.implementation.dependencies.each { + println("implementation " + it + " " + it.artifacts*.classifier) + } + configurations.destination1.dependencies.each { + println("destination1 " + it + " " + it.artifacts*.classifier) + } + configurations.destination2.dependencies.each { + println("destination2 " + it + " " + it.artifacts*.classifier) + } + } + } + """ + file("gradle/libs.versions.toml") << """[libraries] +test = { module = 'org:test', version = '1.0' } +""" + + when: + succeeds "copyAndPrintDependencies" + + then: + outputContains("""implementation org:test:1.0 [alternative] +destination1 org:test:1.0 [alternative] +destination2 org:test:1.0 [alternative]""") + } + } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DefaultDependencyFactory.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DefaultDependencyFactory.java index a2ed83e65591..96e8c7f9927a 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DefaultDependencyFactory.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DefaultDependencyFactory.java @@ -75,14 +75,15 @@ public Dependency createDependency(Object dependencyNotation) { Dependency dependency; if (dependencyNotation instanceof Dependency && !(dependencyNotation instanceof MinimalExternalModuleDependency)) { dependency = (Dependency) dependencyNotation; + injectServices(dependency); } else { dependency = dependencyNotationParser.getNotationParser().parseNotation(dependencyNotation); } - injectServices(dependency); return dependency; } - private void injectServices(Dependency dependency) { + @Override + public void injectServices(Dependency dependency) { if (dependency instanceof AbstractModuleDependency) { AbstractModuleDependency moduleDependency = (AbstractModuleDependency) dependency; moduleDependency.setAttributesFactory(attributesFactory); diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultExternalModuleDependency.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultExternalModuleDependency.java index 568858d08f1a..72ff9177baff 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultExternalModuleDependency.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultExternalModuleDependency.java @@ -36,7 +36,7 @@ public DefaultExternalModuleDependency(ModuleIdentifier id, MutableVersionConstr } @Override - public DefaultExternalModuleDependency copy() { + public ExternalModuleDependency copy() { DefaultExternalModuleDependency copiedModuleDependency = new DefaultExternalModuleDependency(getGroup(), getName(), getVersion(), getTargetConfiguration()); copyTo(copiedModuleDependency); return copiedModuleDependency; diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependency.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependency.java index 1222bfdedf38..15f1563cd19d 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependency.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependency.java @@ -15,13 +15,12 @@ */ package org.gradle.api.internal.artifacts.dependencies; -import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.ModuleIdentifier; import org.gradle.api.artifacts.MutableVersionConstraint; import java.io.Serializable; -public class DefaultMinimalDependency extends DefaultExternalModuleDependency implements MinimalExternalModuleDependency, Serializable { +public class DefaultMinimalDependency extends DefaultExternalModuleDependency implements MinimalExternalModuleDependencyInternal, Serializable { public DefaultMinimalDependency(ModuleIdentifier module, MutableVersionConstraint versionConstraint) { super(module, versionConstraint); } @@ -41,6 +40,11 @@ protected void validateMutation(Object currentValue, Object newValue) { validateMutation(); } + @Override + public void copyTo(AbstractExternalModuleDependency target) { + super.copyTo(target); + } + // Intentionally changes to the mutable version. @Override public DefaultMutableMinimalDependency copy() { diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java index 77c00d044182..2d248d26f5b6 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java @@ -18,38 +18,96 @@ import org.gradle.api.Action; import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.ModuleDependencyCapabilitiesHandler; +import org.gradle.api.artifacts.ModuleIdentifier; +import org.gradle.api.artifacts.MutableVersionConstraint; import org.gradle.api.attributes.AttributeContainer; +import org.gradle.api.internal.artifacts.dsl.dependencies.ModuleFactoryHelper; import org.gradle.internal.Actions; +import org.gradle.util.internal.GUtil; import javax.annotation.Nullable; -public class DefaultMinimalDependencyVariant extends DefaultExternalModuleDependency implements MinimalExternalModuleDependency, DependencyVariant { - private final MinimalExternalModuleDependency delegate; - private final Action attributesMutator; - private final Action capabilitiesMutator; - private final String classifier; - private final String artifactType; - - public DefaultMinimalDependencyVariant(MinimalExternalModuleDependency delegate, - @Nullable Action attributesMutator, - @Nullable Action capabilitiesMutator, - @Nullable String classifier, - @Nullable String artifactType) { - super(delegate.getModule(), new DefaultMutableVersionConstraint(delegate.getVersionConstraint())); - this.delegate = delegate; - boolean delegateIsVariant = delegate instanceof DefaultMinimalDependencyVariant; - this.attributesMutator = delegateIsVariant ? Actions.composite(((DefaultMinimalDependencyVariant) delegate).attributesMutator, attributesMutator == null ? Actions.doNothing() : attributesMutator) : attributesMutator; - this.capabilitiesMutator = delegateIsVariant ? Actions.composite(((DefaultMinimalDependencyVariant) delegate).capabilitiesMutator, capabilitiesMutator == null ? Actions.doNothing() : capabilitiesMutator) : capabilitiesMutator; - if (classifier == null && delegateIsVariant) { - classifier = ((DefaultMinimalDependencyVariant) delegate).getClassifier(); - } - if (artifactType == null && delegateIsVariant) { - artifactType = ((DefaultMinimalDependencyVariant) delegate).getArtifactType(); +public class DefaultMinimalDependencyVariant extends DefaultExternalModuleDependency implements MinimalExternalModuleDependencyInternal, DependencyVariant { + private Action attributesMutator; + private Action capabilitiesMutator; + private String classifier; + private String artifactType; + + public static DefaultMinimalDependencyVariant create( + MinimalExternalModuleDependency delegate, + @Nullable Action attributesMutator, + @Nullable Action capabilitiesMutator, + @Nullable String classifier, + @Nullable String artifactType + ) { + attributesMutator = GUtil.elvis(attributesMutator, Actions.doNothing()); + capabilitiesMutator = GUtil.elvis(capabilitiesMutator, Actions.doNothing()); + + if (delegate instanceof DefaultMinimalDependencyVariant) { + DefaultMinimalDependencyVariant defaultDelegate = (DefaultMinimalDependencyVariant) delegate; + return new DefaultMinimalDependencyVariant( + delegate.getModule(), + new DefaultMutableVersionConstraint(delegate.getVersionConstraint()), + Actions.composite(defaultDelegate.attributesMutator, attributesMutator), + Actions.composite(defaultDelegate.capabilitiesMutator, capabilitiesMutator), + classifier == null ? defaultDelegate.getClassifier() : classifier, + artifactType == null ? defaultDelegate.getArtifactType() : artifactType + ); + } else { + return new DefaultMinimalDependencyVariant( + delegate.getModule(), + new DefaultMutableVersionConstraint(delegate.getVersionConstraint()), + attributesMutator, + capabilitiesMutator, + classifier, + artifactType + ); } + } + + private DefaultMinimalDependencyVariant( + ModuleIdentifier id, + MutableVersionConstraint versionConstraint, + Action attributesMutator, + Action capabilitiesMutator, + @Nullable String classifier, + @Nullable String artifactType + ) { + super(id, versionConstraint); + this.attributesMutator = attributesMutator; + this.capabilitiesMutator = capabilitiesMutator; this.classifier = classifier; this.artifactType = artifactType; } + @Override + public void copyTo(AbstractExternalModuleDependency target) { + super.copyTo(target); + if (target instanceof DefaultMinimalDependencyVariant) { + DefaultMinimalDependencyVariant depVariant = (DefaultMinimalDependencyVariant) target; + depVariant.attributesMutator = attributesMutator; + depVariant.capabilitiesMutator = capabilitiesMutator; + depVariant.classifier = classifier; + depVariant.artifactType = artifactType; + } else { + target.attributes(attributesMutator); + target.capabilities(capabilitiesMutator); + if (classifier != null || artifactType != null) { + ModuleFactoryHelper.addExplicitArtifactsIfDefined(target, artifactType, classifier); + } + } + } + + @Override + public MinimalExternalModuleDependency copy() { + DefaultMinimalDependencyVariant dependency = new DefaultMinimalDependencyVariant( + getModule(), new DefaultMutableVersionConstraint(getVersionConstraint()), + attributesMutator, capabilitiesMutator, classifier, artifactType + ); + copyTo(dependency); + return dependency; + } + @Override public void because(String reason) { validateMutation(); @@ -67,16 +125,12 @@ protected void validateMutation(Object currentValue, Object newValue) { @Override public void mutateAttributes(AttributeContainer attributes) { - if (attributesMutator!= null) { - attributesMutator.execute(attributes); - } + attributesMutator.execute(attributes); } @Override public void mutateCapabilities(ModuleDependencyCapabilitiesHandler capabilitiesHandler) { - if (capabilitiesMutator != null) { - capabilitiesMutator.execute(capabilitiesHandler); - } + capabilitiesMutator.execute(capabilitiesHandler); } @Nullable @@ -93,6 +147,11 @@ public String getArtifactType() { @Override public String toString() { - return delegate.toString(); + return "DefaultMinimalDependencyVariant{" + + ", attributesMutator=" + attributesMutator + + ", capabilitiesMutator=" + capabilitiesMutator + + ", classifier='" + classifier + '\'' + + ", artifactType='" + artifactType + '\'' + + "} " + super.toString(); } } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMutableMinimalDependency.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMutableMinimalDependency.java index c51481ede0a4..6ce58307d727 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMutableMinimalDependency.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMutableMinimalDependency.java @@ -15,13 +15,12 @@ */ package org.gradle.api.internal.artifacts.dependencies; -import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.ModuleIdentifier; import org.gradle.api.artifacts.MutableVersionConstraint; import java.io.Serializable; -public class DefaultMutableMinimalDependency extends DefaultExternalModuleDependency implements MinimalExternalModuleDependency, Serializable { +public class DefaultMutableMinimalDependency extends DefaultExternalModuleDependency implements MinimalExternalModuleDependencyInternal, Serializable { public DefaultMutableMinimalDependency(ModuleIdentifier module, MutableVersionConstraint versionConstraint) { super(module, versionConstraint); } @@ -33,6 +32,11 @@ public DefaultMutableMinimalDependency copy() { return dependency; } + @Override + public void copyTo(AbstractExternalModuleDependency target) { + super.copyTo(target); + } + public String toString() { String versionConstraintAsString = getVersionConstraint().toString(); return versionConstraintAsString.isEmpty() diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java new file mode 100644 index 000000000000..0c2f103470f6 --- /dev/null +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java @@ -0,0 +1,23 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.api.internal.artifacts.dependencies; + +import org.gradle.api.artifacts.MinimalExternalModuleDependency; + +public interface MinimalExternalModuleDependencyInternal extends MinimalExternalModuleDependency { + void copyTo(AbstractExternalModuleDependency target); +} diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java index 25841fd607c1..7d07ec6a2d49 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java @@ -414,7 +414,9 @@ public Provider variantOf(Provider { DefaultExternalModuleDependencyVariantSpec spec = objects.newInstance(DefaultExternalModuleDependencyVariantSpec.class, objects, dep); variantSpec.execute(spec); - return new DefaultMinimalDependencyVariant(dep, spec.attributesAction, spec.capabilitiesMutator, spec.classifier, spec.artifactType); + DefaultMinimalDependencyVariant newDep = DefaultMinimalDependencyVariant.create(dep, spec.attributesAction, spec.capabilitiesMutator, spec.classifier, spec.artifactType); + dependencyFactory.injectServices(newDep); + return newDep; }); } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java index e7e7bde38980..919e112081bc 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java @@ -27,11 +27,11 @@ import org.gradle.api.file.FileCollection; import org.gradle.api.internal.ClassPathRegistry; import org.gradle.api.internal.artifacts.DefaultProjectDependencyFactory; +import org.gradle.api.internal.artifacts.dependencies.AbstractModuleDependency; import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency; import org.gradle.api.internal.artifacts.dependencies.DefaultMutableMinimalDependency; -import org.gradle.api.internal.artifacts.dependencies.DependencyVariant; +import org.gradle.api.internal.artifacts.dependencies.MinimalExternalModuleDependencyInternal; import org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactoryInternal; -import org.gradle.api.internal.artifacts.dsl.dependencies.ModuleFactoryHelper; import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.internal.file.FileCollectionFactory; import org.gradle.api.internal.runtimeshaded.RuntimeShadedJarFactory; @@ -61,7 +61,7 @@ public static DependencyNotationParser create(Instantiator instantiator, NotationConverter stringNotationConverter = new DependencyStringNotationConverter<>(instantiator, DefaultExternalModuleDependency.class, stringInterner); NotationConverter minimalExternalDependencyNotationConverter = - new MinimalExternalDependencyNotationConverter(instantiator, attributesFactory, capabilityNotationParser); + new MinimalExternalDependencyNotationConverter(instantiator); MapNotationConverter mapNotationConverter = new DependencyMapNotationConverter<>(instantiator, DefaultExternalModuleDependency.class); NotationConverter filesNotationConverter = @@ -80,8 +80,9 @@ public static DependencyNotationParser create(Instantiator instantiator, .fromType(DependencyFactoryInternal.ClassPathNotation.class, dependencyClassPathNotationConverter) .invalidNotationMessage("Comprehensive documentation on dependency notations is available in DSL reference for DependencyHandler type.") .toComposite(); - return new DependencyNotationParser( - notationParser, + return + new DependencyNotationParser( + new ServiceInjectingNotationParser(notationParser, attributesFactory, capabilityNotationParser), new NotationConverterToNotationParserAdapter<>(stringNotationConverter), new NotationConverterToNotationParserAdapter<>(minimalExternalDependencyNotationConverter), new NotationConverterToNotationParserAdapter<>(mapNotationConverter), @@ -138,37 +139,57 @@ public NotationParser getNotationParser() { private static class MinimalExternalDependencyNotationConverter implements NotationConverter { private final Instantiator instantiator; + + public MinimalExternalDependencyNotationConverter(Instantiator instantiator) { + this.instantiator = instantiator; + } + + @Override + public void convert(MinimalExternalModuleDependency notation, NotationConvertResult result) throws TypeConversionException { + DefaultMutableMinimalDependency moduleDependency = instantiator.newInstance(DefaultMutableMinimalDependency.class, notation.getModule(), notation.getVersionConstraint()); + MinimalExternalModuleDependencyInternal internal = (MinimalExternalModuleDependencyInternal) notation; + internal.copyTo(moduleDependency); + result.converted(moduleDependency); + } + + @Override + public void describe(DiagnosticsVisitor visitor) { + } + } + + private static class ServiceInjectingNotationParser implements NotationParser { + + private final NotationParser delegate; private final ImmutableAttributesFactory attributesFactory; private final NotationParser capabilityNotationParser; - public MinimalExternalDependencyNotationConverter(Instantiator instantiator, ImmutableAttributesFactory attributesFactory, NotationParser capabilityNotationParser) { - this.instantiator = instantiator; + public ServiceInjectingNotationParser( + NotationParser delegate, + ImmutableAttributesFactory attributesFactory, + NotationParser capabilityNotationParser + ) { + this.delegate = delegate; this.attributesFactory = attributesFactory; this.capabilityNotationParser = capabilityNotationParser; } @Override - public void convert(MinimalExternalModuleDependency notation, NotationConvertResult result) throws TypeConversionException { - DefaultMutableMinimalDependency moduleDependency = instantiator.newInstance(DefaultMutableMinimalDependency.class, notation.getModule(), notation.getVersionConstraint()); - if (notation instanceof DependencyVariant) { + public Dependency parseNotation(Object notation) throws TypeConversionException { + Dependency parsed = delegate.parseNotation(notation); + + if (parsed instanceof AbstractModuleDependency) { + AbstractModuleDependency moduleDependency = (AbstractModuleDependency) parsed; moduleDependency.setAttributesFactory(attributesFactory); moduleDependency.setCapabilityNotationParser(capabilityNotationParser); - DependencyVariant dependencyVariant = (DependencyVariant) notation; - moduleDependency.attributes(dependencyVariant::mutateAttributes); - moduleDependency.capabilities(dependencyVariant::mutateCapabilities); - String classifier = dependencyVariant.getClassifier(); - String artifactType = dependencyVariant.getArtifactType(); - if (classifier != null || artifactType != null) { - ModuleFactoryHelper.addExplicitArtifactsIfDefined(moduleDependency, artifactType, classifier); - } } - result.converted(moduleDependency); + + return parsed; } @Override public void describe(DiagnosticsVisitor visitor) { + delegate.describe(visitor); } - - } + } From 3dd33851c80524b4febdf781e29160e4fd4d1e62 Mon Sep 17 00:00:00 2001 From: Justin Van Dort Date: Mon, 19 Dec 2022 17:05:43 -0500 Subject: [PATCH 2/3] Make configuration cache compatible --- .../api/ArtifactDeclarationIntegrationTest.groovy | 9 +++++---- .../api/internal/notations/DependencyNotationParser.java | 3 +-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy index 5f929a0eb83a..407f973ea7cb 100644 --- a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy +++ b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy @@ -524,11 +524,12 @@ task checkArtifacts { } task copyAndPrintDependencies { + configurations.implementation.dependencies.each { + project.dependencies.add("destination1", it) + configurations.destination2.dependencies.add(it) + } + doLast { - configurations.implementation.dependencies.each { - project.dependencies.add("destination1", it) - configurations.destination2.dependencies.add(it) - } configurations.implementation.dependencies.each { println("implementation " + it + " " + it.artifacts*.classifier) } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java index 919e112081bc..a628378aa0f5 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java @@ -80,8 +80,7 @@ public static DependencyNotationParser create(Instantiator instantiator, .fromType(DependencyFactoryInternal.ClassPathNotation.class, dependencyClassPathNotationConverter) .invalidNotationMessage("Comprehensive documentation on dependency notations is available in DSL reference for DependencyHandler type.") .toComposite(); - return - new DependencyNotationParser( + return new DependencyNotationParser( new ServiceInjectingNotationParser(notationParser, attributesFactory, capabilityNotationParser), new NotationConverterToNotationParserAdapter<>(stringNotationConverter), new NotationConverterToNotationParserAdapter<>(minimalExternalDependencyNotationConverter), From 4fed83ebb6bc991f754eb374823d47803fc18b1e Mon Sep 17 00:00:00 2001 From: Justin Van Dort Date: Tue, 20 Dec 2022 00:36:17 -0500 Subject: [PATCH 3/3] Fix properly by injecting services into minimal dependencies when they are created initially --- subprojects/base-services/build.gradle.kts | 1 - .../java/org/gradle/util/internal/GUtil.java | 2 - .../AbstractModuleDependency.java | 6 ++- .../DependencyFactoryInternal.java | 1 - .../artifacts/DefaultDependencyFactory.java | 5 +-- ...ependencyManagementBuildScopeServices.java | 23 ++++++---- .../DefaultMinimalDependencyVariant.java | 42 ++++++++---------- ...nimalExternalModuleDependencyInternal.java | 7 +++ .../dsl/CapabilityNotationParser.java | 28 ++++++++++++ .../dsl/CapabilityNotationParserFactory.java | 22 +++++++--- .../DefaultDependencyHandler.java | 4 +- .../AbstractExternalDependencyFactory.java | 33 +++++++++----- .../catalog/DefaultDependenciesAccessors.java | 14 +++++- .../DefaultExternalDependencyFactory.java | 12 ++++- ...DefaultExternalModuleDependencyBundle.java | 28 ++++++++++++ .../catalog/LibrariesSourceGenerator.java | 12 +++-- .../internal/catalog/VersionCatalogView.java | 23 ++++++---- .../notations/DependencyNotationParser.java | 44 +------------------ .../LibrariesSourceGeneratorTest.groovy | 8 +++- 19 files changed, 197 insertions(+), 118 deletions(-) create mode 100644 subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParser.java create mode 100644 subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalModuleDependencyBundle.java diff --git a/subprojects/base-services/build.gradle.kts b/subprojects/base-services/build.gradle.kts index 4c408aabc608..e8c828e796ea 100644 --- a/subprojects/base-services/build.gradle.kts +++ b/subprojects/base-services/build.gradle.kts @@ -24,7 +24,6 @@ tasks.named("jmhCompileGeneratedClasses") { moduleIdentity.createBuildReceipt() dependencies { - api(libs.jetbrainsAnnotations) api(project(":base-annotations")) api(project(":worker-services")) api(project(":hashing")) diff --git a/subprojects/base-services/src/main/java/org/gradle/util/internal/GUtil.java b/subprojects/base-services/src/main/java/org/gradle/util/internal/GUtil.java index 77e62b2b632c..11e2938da254 100644 --- a/subprojects/base-services/src/main/java/org/gradle/util/internal/GUtil.java +++ b/subprojects/base-services/src/main/java/org/gradle/util/internal/GUtil.java @@ -24,7 +24,6 @@ import org.gradle.internal.Factory; import org.gradle.internal.IoActions; import org.gradle.internal.UncheckedException; -import org.jetbrains.annotations.Contract; import javax.annotation.Nullable; import java.io.File; @@ -158,7 +157,6 @@ public static boolean isTrue(@Nullable Object object) { * would trigger early configuration. */ @Nullable - @Contract("!null, _ -> param1; null, !null -> param2; null, null -> null") public static T elvis(@Nullable T object, @Nullable T defaultValue) { return isTrue(object) ? object : defaultValue; } diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dependencies/AbstractModuleDependency.java b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dependencies/AbstractModuleDependency.java index bd72dffb9326..3dea85d27466 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dependencies/AbstractModuleDependency.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dependencies/AbstractModuleDependency.java @@ -275,10 +275,14 @@ public void setCapabilityNotationParser(NotationParser capab this.capabilityNotationParser = capabilityNotationParser; } - protected ImmutableAttributesFactory getAttributesFactory() { + public ImmutableAttributesFactory getAttributesFactory() { return attributesFactory; } + public NotationParser getCapabilityNotationParser() { + return capabilityNotationParser; + } + private void setAttributes(AttributeContainerInternal attributes) { this.attributes = attributes; } diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DependencyFactoryInternal.java b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DependencyFactoryInternal.java index 6d8869455ae4..c4d942a7f418 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DependencyFactoryInternal.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DependencyFactoryInternal.java @@ -47,5 +47,4 @@ enum ClassPathNotation { DependencyConstraint createDependencyConstraint(Object dependencyNotation); ClientModule createModule(Object dependencyNotation, Closure configureClosure); ProjectDependency createProjectDependencyFromMap(ProjectFinder projectFinder, Map map); - void injectServices(Dependency dependency); } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DefaultDependencyFactory.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DefaultDependencyFactory.java index 96e8c7f9927a..a2ed83e65591 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DefaultDependencyFactory.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DefaultDependencyFactory.java @@ -75,15 +75,14 @@ public Dependency createDependency(Object dependencyNotation) { Dependency dependency; if (dependencyNotation instanceof Dependency && !(dependencyNotation instanceof MinimalExternalModuleDependency)) { dependency = (Dependency) dependencyNotation; - injectServices(dependency); } else { dependency = dependencyNotationParser.getNotationParser().parseNotation(dependencyNotation); } + injectServices(dependency); return dependency; } - @Override - public void injectServices(Dependency dependency) { + private void injectServices(Dependency dependency) { if (dependency instanceof AbstractModuleDependency) { AbstractModuleDependency moduleDependency = (AbstractModuleDependency) dependency; moduleDependency.setAttributesFactory(attributesFactory); diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DependencyManagementBuildScopeServices.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DependencyManagementBuildScopeServices.java index 60f269101415..ac98101a459c 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DependencyManagementBuildScopeServices.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DependencyManagementBuildScopeServices.java @@ -21,7 +21,6 @@ import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Sets; import org.gradle.StartParameter; -import org.gradle.api.capabilities.Capability; import org.gradle.api.internal.ClassPathRegistry; import org.gradle.api.internal.CollectionCallbackActionDecorator; import org.gradle.api.internal.DocumentationRegistry; @@ -30,6 +29,7 @@ import org.gradle.api.internal.artifacts.component.ComponentIdentifierFactory; import org.gradle.api.internal.artifacts.component.DefaultComponentIdentifierFactory; import org.gradle.api.internal.artifacts.configurations.DependencyMetaDataProvider; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParserFactory; import org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactoryInternal; import org.gradle.api.internal.artifacts.ivyservice.ArtifactCacheLockingManager; @@ -215,7 +215,6 @@ import org.gradle.internal.service.ServiceRegistry; import org.gradle.internal.snapshot.ValueSnapshot; import org.gradle.internal.snapshot.ValueSnapshotter; -import org.gradle.internal.typeconversion.NotationParser; import org.gradle.internal.vfs.VirtualFileSystem; import org.gradle.util.internal.BuildCommencedTimeProvider; import org.gradle.util.internal.SimpleMapInterner; @@ -274,11 +273,15 @@ VersionComparator createVersionComparator() { return new DefaultVersionComparator(); } + CapabilityNotationParser createCapabilityNotationParser() { + return new CapabilityNotationParserFactory(false).create(); + } + DefaultProjectDependencyFactory createProjectDependencyFactory( Instantiator instantiator, StartParameter startParameter, - ImmutableAttributesFactory attributesFactory) { - NotationParser capabilityNotationParser = new CapabilityNotationParserFactory(false).create(); + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser) { return new DefaultProjectDependencyFactory(instantiator, startParameter.isBuildProjectDependencies(), capabilityNotationParser, attributesFactory); } @@ -290,13 +293,13 @@ DependencyFactoryInternal createDependencyFactory( FileCollectionFactory fileCollectionFactory, RuntimeShadedJarFactory runtimeShadedJarFactory, ImmutableAttributesFactory attributesFactory, - SimpleMapInterner stringInterner) { - NotationParser capabilityNotationParser = new CapabilityNotationParserFactory(false).create(); + SimpleMapInterner stringInterner, + CapabilityNotationParser capabilityNotationParser) { ProjectDependencyFactory projectDependencyFactory = new ProjectDependencyFactory(factory); return new DefaultDependencyFactory( instantiator, - DependencyNotationParser.create(instantiator, factory, classPathRegistry, fileCollectionFactory, runtimeShadedJarFactory, currentGradleInstallation, stringInterner, attributesFactory, capabilityNotationParser), + DependencyNotationParser.create(instantiator, factory, classPathRegistry, fileCollectionFactory, runtimeShadedJarFactory, currentGradleInstallation, stringInterner), DependencyConstraintNotationParser.parser(instantiator, factory, stringInterner, attributesFactory), new ClientModuleNotationParserFactory(instantiator, stringInterner).create(), capabilityNotationParser, projectDependencyFactory, @@ -677,8 +680,10 @@ DependenciesAccessors createDependenciesAccessorGenerator(ClassPathRegistry regi ExecutionEngine executionEngine, FeaturePreviews featurePreviews, FileCollectionFactory fileCollectionFactory, - InputFingerprinter inputFingerprinter) { - return new DefaultDependenciesAccessors(registry, workspace, factory, featurePreviews, executionEngine, fileCollectionFactory, inputFingerprinter); + InputFingerprinter inputFingerprinter, + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser) { + return new DefaultDependenciesAccessors(registry, workspace, factory, featurePreviews, executionEngine, fileCollectionFactory, inputFingerprinter, attributesFactory, capabilityNotationParser); } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java index 2d248d26f5b6..aaeb98f7393b 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java @@ -33,36 +33,32 @@ public class DefaultMinimalDependencyVariant extends DefaultExternalModuleDepend private String classifier; private String artifactType; - public static DefaultMinimalDependencyVariant create( - MinimalExternalModuleDependency delegate, - @Nullable Action attributesMutator, - @Nullable Action capabilitiesMutator, - @Nullable String classifier, - @Nullable String artifactType + public DefaultMinimalDependencyVariant(MinimalExternalModuleDependency delegate, + @Nullable Action attributesMutator, + @Nullable Action capabilitiesMutator, + @Nullable String classifier, + @Nullable String artifactType ) { + super(delegate.getModule(), new DefaultMutableVersionConstraint(delegate.getVersionConstraint())); + attributesMutator = GUtil.elvis(attributesMutator, Actions.doNothing()); capabilitiesMutator = GUtil.elvis(capabilitiesMutator, Actions.doNothing()); if (delegate instanceof DefaultMinimalDependencyVariant) { - DefaultMinimalDependencyVariant defaultDelegate = (DefaultMinimalDependencyVariant) delegate; - return new DefaultMinimalDependencyVariant( - delegate.getModule(), - new DefaultMutableVersionConstraint(delegate.getVersionConstraint()), - Actions.composite(defaultDelegate.attributesMutator, attributesMutator), - Actions.composite(defaultDelegate.capabilitiesMutator, capabilitiesMutator), - classifier == null ? defaultDelegate.getClassifier() : classifier, - artifactType == null ? defaultDelegate.getArtifactType() : artifactType - ); + this.attributesMutator = Actions.composite(((DefaultMinimalDependencyVariant) delegate).attributesMutator, attributesMutator); + this.capabilitiesMutator = Actions.composite(((DefaultMinimalDependencyVariant) delegate).capabilitiesMutator, capabilitiesMutator); + this.classifier = GUtil.elvis(classifier, ((DefaultMinimalDependencyVariant) delegate).getClassifier()); + this.artifactType = GUtil.elvis(classifier, ((DefaultMinimalDependencyVariant) delegate).getArtifactType()); } else { - return new DefaultMinimalDependencyVariant( - delegate.getModule(), - new DefaultMutableVersionConstraint(delegate.getVersionConstraint()), - attributesMutator, - capabilitiesMutator, - classifier, - artifactType - ); + this.attributesMutator = attributesMutator; + this.capabilitiesMutator = capabilitiesMutator; + this.classifier = classifier; + this.artifactType = artifactType; } + + MinimalExternalModuleDependencyInternal internal = (MinimalExternalModuleDependencyInternal) delegate; + setAttributesFactory(internal.getAttributesFactory()); + setCapabilityNotationParser(internal.getCapabilityNotationParser()); } private DefaultMinimalDependencyVariant( diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java index 0c2f103470f6..73e7a1d53850 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java @@ -17,7 +17,14 @@ package org.gradle.api.internal.artifacts.dependencies; import org.gradle.api.artifacts.MinimalExternalModuleDependency; +import org.gradle.api.capabilities.Capability; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; +import org.gradle.internal.typeconversion.NotationParser; public interface MinimalExternalModuleDependencyInternal extends MinimalExternalModuleDependency { void copyTo(AbstractExternalModuleDependency target); + + ImmutableAttributesFactory getAttributesFactory(); + + NotationParser getCapabilityNotationParser(); } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParser.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParser.java new file mode 100644 index 000000000000..ecf18cb812d3 --- /dev/null +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParser.java @@ -0,0 +1,28 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.api.internal.artifacts.dsl; + +import org.gradle.api.capabilities.Capability; +import org.gradle.internal.typeconversion.NotationParser; + +/** + * A concrete type for a generic {@link NotationParser} that parses {@link Capability}s. + *

+ * This concrete type is necessary so that it can be injected into version catalog generated sources. + */ +public interface CapabilityNotationParser extends NotationParser { +} diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParserFactory.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParserFactory.java index dfb3a90817e4..77e4535137aa 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParserFactory.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParserFactory.java @@ -25,14 +25,15 @@ import org.gradle.internal.typeconversion.MapNotationConverter; import org.gradle.internal.typeconversion.NotationParser; import org.gradle.internal.typeconversion.NotationParserBuilder; +import org.gradle.internal.typeconversion.TypeConversionException; import org.gradle.internal.typeconversion.TypedNotationConverter; import javax.annotation.Nonnull; import javax.annotation.Nullable; public class CapabilityNotationParserFactory implements Factory> { - private final static NotationParser STRICT_CONVERTER = createSingletonConverter(true); - private final static NotationParser LENIENT_CONVERTER = createSingletonConverter(false); + private final static CapabilityNotationParser STRICT_CONVERTER = createSingletonConverter(true); + private final static CapabilityNotationParser LENIENT_CONVERTER = createSingletonConverter(false); private final boolean versionIsRequired; @@ -40,16 +41,27 @@ public CapabilityNotationParserFactory(boolean versionIsRequired) { this.versionIsRequired = versionIsRequired; } - private static NotationParser createSingletonConverter(boolean strict) { - return NotationParserBuilder.toType(Capability.class) + private static CapabilityNotationParser createSingletonConverter(boolean strict) { + NotationParser parser = NotationParserBuilder.toType(Capability.class) .converter(new StringNotationParser(strict)) .converter(strict ? new StrictCapabilityMapNotationParser() : new LenientCapabilityMapNotationParser()) .toComposite(); + return new CapabilityNotationParser() { + @Override + public Capability parseNotation(Object notation) throws TypeConversionException { + return parser.parseNotation(notation); + } + + @Override + public void describe(DiagnosticsVisitor visitor) { + parser.describe(visitor); + } + }; } @Nonnull @Override - public NotationParser create() { + public CapabilityNotationParser create() { // Currently the converter is stateless, doesn't need any external context, so for performance we return a singleton return versionIsRequired ? STRICT_CONVERTER : LENIENT_CONVERTER; } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java index 7d07ec6a2d49..25841fd607c1 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java @@ -414,9 +414,7 @@ public Provider variantOf(Provider { DefaultExternalModuleDependencyVariantSpec spec = objects.newInstance(DefaultExternalModuleDependencyVariantSpec.class, objects, dep); variantSpec.execute(spec); - DefaultMinimalDependencyVariant newDep = DefaultMinimalDependencyVariant.create(dep, spec.attributesAction, spec.capabilitiesMutator, spec.classifier, spec.artifactType); - dependencyFactory.injectServices(newDep); - return newDep; + return new DefaultMinimalDependencyVariant(dep, spec.attributesAction, spec.capabilitiesMutator, spec.classifier, spec.artifactType); }); } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/AbstractExternalDependencyFactory.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/AbstractExternalDependencyFactory.java index 9e0539bbea5c..a661201b6d8b 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/AbstractExternalDependencyFactory.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/AbstractExternalDependencyFactory.java @@ -21,6 +21,8 @@ import org.gradle.api.internal.artifacts.ImmutableVersionConstraint; import org.gradle.api.internal.artifacts.dependencies.DefaultMinimalDependency; import org.gradle.api.internal.artifacts.dependencies.DefaultMutableVersionConstraint; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; @@ -28,13 +30,14 @@ import org.gradle.plugin.use.PluginDependency; import javax.inject.Inject; -import java.util.ArrayList; import java.util.stream.Collectors; public abstract class AbstractExternalDependencyFactory implements ExternalModuleDependencyFactory { protected final DefaultVersionCatalog config; protected final ProviderFactory providers; protected final ObjectFactory objects; + protected final ImmutableAttributesFactory attributesFactory; + protected final CapabilityNotationParser capabilityNotationParser; @SuppressWarnings("unused") public static abstract class SubDependencyFactory implements ExternalModuleDependencyFactory { @@ -54,11 +57,15 @@ public Provider create(String alias) { @Inject protected AbstractExternalDependencyFactory(DefaultVersionCatalog config, ProviderFactory providers, - ObjectFactory objects + ObjectFactory objects, + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser ) { this.config = config; this.providers = providers; this.objects = objects; + this.attributesFactory = attributesFactory; + this.capabilityNotationParser = capabilityNotationParser; } @Override @@ -66,14 +73,17 @@ public Provider create(String alias) { return providers.of( DependencyValueSource.class, spec -> spec.getParameters().getDependencyData().set(config.getDependencyData(alias)) - ).map(AbstractExternalDependencyFactory::createMinimalDependency); + ).map(x -> createMinimalDependency(x, attributesFactory, capabilityNotationParser)); } - private static DefaultMinimalDependency createMinimalDependency(DependencyModel data) { + private static DefaultMinimalDependency createMinimalDependency(DependencyModel data, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { ImmutableVersionConstraint version = data.getVersion(); - return new DefaultMinimalDependency( + DefaultMinimalDependency result = new DefaultMinimalDependency( DefaultModuleIdentifier.newId(data.getGroup(), data.getName()), new DefaultMutableVersionConstraint(version) ); + result.setAttributesFactory(attributesFactory); + result.setCapabilityNotationParser(capabilityNotationParser); + return result; } public static class VersionFactory { @@ -118,11 +128,15 @@ public static class BundleFactory { protected final ProviderFactory providers; protected final DefaultVersionCatalog config; protected final ObjectFactory objects; + protected final ImmutableAttributesFactory attributesFactory; + protected final CapabilityNotationParser capabilityNotationParser; - public BundleFactory(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config) { + public BundleFactory(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { this.objects = objects; this.providers = providers; this.config = config; + this.attributesFactory = attributesFactory; + this.capabilityNotationParser = capabilityNotationParser; } protected Provider createBundle(String name) { @@ -134,13 +148,10 @@ protected Provider createBundle(String name) { params.getBundleName().set(name); }) ).map(dataList -> dataList.stream() - .map(AbstractExternalDependencyFactory::createMinimalDependency) - .collect(Collectors.toCollection(DefaultBundle::new)))); + .map(x -> createMinimalDependency(x, attributesFactory, capabilityNotationParser)) + .collect(Collectors.toCollection(DefaultExternalModuleDependencyBundle::new)))); return property; } - - private static class DefaultBundle extends ArrayList implements ExternalModuleDependencyBundle { - } } public static class PluginFactory { diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultDependenciesAccessors.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultDependenciesAccessors.java index abb9ac67afce..dbf4a18c3245 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultDependenciesAccessors.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultDependenciesAccessors.java @@ -30,7 +30,9 @@ import org.gradle.api.internal.FeaturePreviews; import org.gradle.api.internal.SettingsInternal; import org.gradle.api.internal.artifacts.DefaultProjectDependencyFactory; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; import org.gradle.api.internal.artifacts.dsl.dependencies.ProjectFinder; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.internal.file.FileCollectionFactory; import org.gradle.api.internal.initialization.ClassLoaderScope; import org.gradle.api.internal.project.ProjectInternal; @@ -96,6 +98,9 @@ public class DefaultDependenciesAccessors implements DependenciesAccessors { private final ExecutionEngine engine; private final FileCollectionFactory fileCollectionFactory; private final InputFingerprinter inputFingerprinter; + private final ImmutableAttributesFactory attributesFactory; + private final CapabilityNotationParser capabilityNotationParser; + private final List models = Lists.newArrayList(); private final Map> factories = Maps.newHashMap(); @@ -110,7 +115,10 @@ public DefaultDependenciesAccessors(ClassPathRegistry registry, FeaturePreviews featurePreview, ExecutionEngine engine, FileCollectionFactory fileCollectionFactory, - InputFingerprinter inputFingerprinter) { + InputFingerprinter inputFingerprinter, + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser + ) { this.classPath = registry.getClassPath("DEPENDENCIES-EXTENSION-COMPILER"); this.workspace = workspace; this.projectDependencyFactory = projectDependencyFactory; @@ -118,6 +126,8 @@ public DefaultDependenciesAccessors(ClassPathRegistry registry, this.engine = engine; this.fileCollectionFactory = fileCollectionFactory; this.inputFingerprinter = inputFingerprinter; + this.attributesFactory = attributesFactory; + this.capabilityNotationParser = capabilityNotationParser; } @Override @@ -239,7 +249,7 @@ public void createExtensions(ProjectInternal project) { } if (factory != null) { container.create(model.getName(), factory, model); - catalogs.put(model.getName(), new VersionCatalogView(model, providerFactory, project.getObjects())); + catalogs.put(model.getName(), new VersionCatalogView(model, providerFactory, project.getObjects(), attributesFactory, capabilityNotationParser)); } } } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalDependencyFactory.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalDependencyFactory.java index 8527b7911af9..5a341fbf8563 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalDependencyFactory.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalDependencyFactory.java @@ -16,13 +16,21 @@ package org.gradle.api.internal.catalog; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.ProviderFactory; public class DefaultExternalDependencyFactory extends AbstractExternalDependencyFactory { - public DefaultExternalDependencyFactory(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects) { - super(config, providers, objects); + public DefaultExternalDependencyFactory( + DefaultVersionCatalog config, + ProviderFactory providers, + ObjectFactory objects, + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser + ) { + super(config, providers, objects, attributesFactory, capabilityNotationParser); } } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalModuleDependencyBundle.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalModuleDependencyBundle.java new file mode 100644 index 000000000000..1df6feb68dc4 --- /dev/null +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalModuleDependencyBundle.java @@ -0,0 +1,28 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.api.internal.catalog; + +import org.gradle.api.artifacts.ExternalModuleDependencyBundle; +import org.gradle.api.artifacts.MinimalExternalModuleDependency; + +import java.util.ArrayList; + +/** + * Default implementation of {@link ExternalModuleDependencyBundle}. + */ +public class DefaultExternalModuleDependencyBundle extends ArrayList implements ExternalModuleDependencyBundle { +} diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/LibrariesSourceGenerator.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/LibrariesSourceGenerator.java index 6c871c5558d3..7d8e3ee34663 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/LibrariesSourceGenerator.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/LibrariesSourceGenerator.java @@ -23,6 +23,8 @@ import org.gradle.api.artifacts.ExternalModuleDependencyBundle; import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.MutableVersionConstraint; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.internal.catalog.problems.VersionCatalogProblem; import org.gradle.api.internal.catalog.problems.VersionCatalogProblemId; import org.gradle.api.model.ObjectFactory; @@ -105,8 +107,8 @@ private void writeLibraryEntryPoint(String className, ClassNode librariesEntryPo writeSubAccessorFieldsOf(pluginsEntryPoint, AccessorKind.plugin); writeLn(); writeLn("@Inject"); - writeLn("public " + className + "(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects) {"); - writeLn(" super(config, providers, objects);"); + writeLn("public " + className + "(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) {"); + writeLn(" super(config, providers, objects, attributesFactory, capabilityNotationParser);"); writeLn("}"); writeLn(); writeLibraryAccessors(librariesEntryPoint); @@ -133,6 +135,8 @@ private void addImports() throws IOException { addImport(AbstractExternalDependencyFactory.class); addImport(DefaultVersionCatalog.class); addImport(Map.class); + addImport(ImmutableAttributesFactory.class); + addImport(CapabilityNotationParser.class); addImport(Inject.class); } @@ -176,7 +180,7 @@ private void writeBundleAccessorClass(ClassNode classNode) throws IOException { indent(() -> { writeSubAccessorFieldsOf(classNode, AccessorKind.bundle); writeLn(); - writeLn("public " + bundleClassName + "(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config) { super(objects, providers, config); }"); + writeLn("public " + bundleClassName + "(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { super(objects, providers, config, attributesFactory, capabilityNotationParser); }"); writeLn(); if (isProvider) { String path = classNode.getFullAlias(); @@ -610,7 +614,7 @@ public String toString() { private enum AccessorKind { library("libraries", "owner"), version("versions", "providers, config"), - bundle("bundles", "objects, providers, config"), + bundle("bundles", "objects, providers, config, attributesFactory, capabilityNotationParser"), plugin("plugins", "providers, config"); private final String description; diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/VersionCatalogView.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/VersionCatalogView.java index 37e06bd5cf57..af3bca9349b0 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/VersionCatalogView.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/VersionCatalogView.java @@ -20,6 +20,8 @@ import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.VersionCatalog; import org.gradle.api.artifacts.VersionConstraint; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory.BundleFactory; import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory.PluginFactory; import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory.VersionFactory; @@ -29,7 +31,6 @@ import org.gradle.internal.deprecation.DeprecationLogger; import org.gradle.plugin.use.PluginDependency; -import javax.inject.Inject; import java.util.List; import java.util.Optional; @@ -39,15 +40,21 @@ public class VersionCatalogView implements VersionCatalog { private final DefaultVersionCatalog config; private final ProviderFactory providerFactory; - private final ExternalModuleDependencyFactory dependencyFactory; - private final ObjectFactory objects; - @Inject - public VersionCatalogView(DefaultVersionCatalog config, ProviderFactory providerFactory, ObjectFactory objects) { + private final ExternalModuleDependencyFactory dependencyFactory; + private final BundleFactory bundleFactory; + + public VersionCatalogView( + DefaultVersionCatalog config, + ProviderFactory providerFactory, + ObjectFactory objects, + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser + ) { this.config = config; this.providerFactory = providerFactory; - this.objects = objects; - this.dependencyFactory = new DefaultExternalDependencyFactory(config, providerFactory, objects); + this.dependencyFactory = new DefaultExternalDependencyFactory(config, providerFactory, objects, attributesFactory, capabilityNotationParser); + this.bundleFactory = new BundleFactory(objects, providerFactory, config, attributesFactory, capabilityNotationParser); } @Override @@ -74,7 +81,7 @@ public final Optional> findLibrary(Str public final Optional> findBundle(String alias) { String normalizedBundle = normalize(alias); if (config.getBundleAliases().contains(normalizedBundle)) { - return Optional.of(new BundleFactory(objects, providerFactory, config).createBundle(normalizedBundle)); + return Optional.of(bundleFactory.createBundle(normalizedBundle)); } return Optional.empty(); } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java index a628378aa0f5..76f6061c161f 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java @@ -23,16 +23,13 @@ import org.gradle.api.artifacts.FileCollectionDependency; import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.ProjectDependency; -import org.gradle.api.capabilities.Capability; import org.gradle.api.file.FileCollection; import org.gradle.api.internal.ClassPathRegistry; import org.gradle.api.internal.artifacts.DefaultProjectDependencyFactory; -import org.gradle.api.internal.artifacts.dependencies.AbstractModuleDependency; import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency; import org.gradle.api.internal.artifacts.dependencies.DefaultMutableMinimalDependency; import org.gradle.api.internal.artifacts.dependencies.MinimalExternalModuleDependencyInternal; import org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactoryInternal; -import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.internal.file.FileCollectionFactory; import org.gradle.api.internal.runtimeshaded.RuntimeShadedJarFactory; import org.gradle.internal.exceptions.DiagnosticsVisitor; @@ -55,9 +52,7 @@ public static DependencyNotationParser create(Instantiator instantiator, FileCollectionFactory fileCollectionFactory, RuntimeShadedJarFactory runtimeShadedJarFactory, CurrentGradleInstallation currentGradleInstallation, - Interner stringInterner, - ImmutableAttributesFactory attributesFactory, - NotationParser capabilityNotationParser) { + Interner stringInterner) { NotationConverter stringNotationConverter = new DependencyStringNotationConverter<>(instantiator, DefaultExternalModuleDependency.class, stringInterner); NotationConverter minimalExternalDependencyNotationConverter = @@ -81,7 +76,7 @@ public static DependencyNotationParser create(Instantiator instantiator, .invalidNotationMessage("Comprehensive documentation on dependency notations is available in DSL reference for DependencyHandler type.") .toComposite(); return new DependencyNotationParser( - new ServiceInjectingNotationParser(notationParser, attributesFactory, capabilityNotationParser), + notationParser, new NotationConverterToNotationParserAdapter<>(stringNotationConverter), new NotationConverterToNotationParserAdapter<>(minimalExternalDependencyNotationConverter), new NotationConverterToNotationParserAdapter<>(mapNotationConverter), @@ -156,39 +151,4 @@ public void describe(DiagnosticsVisitor visitor) { } } - private static class ServiceInjectingNotationParser implements NotationParser { - - private final NotationParser delegate; - private final ImmutableAttributesFactory attributesFactory; - private final NotationParser capabilityNotationParser; - - public ServiceInjectingNotationParser( - NotationParser delegate, - ImmutableAttributesFactory attributesFactory, - NotationParser capabilityNotationParser - ) { - this.delegate = delegate; - this.attributesFactory = attributesFactory; - this.capabilityNotationParser = capabilityNotationParser; - } - - @Override - public Dependency parseNotation(Object notation) throws TypeConversionException { - Dependency parsed = delegate.parseNotation(notation); - - if (parsed instanceof AbstractModuleDependency) { - AbstractModuleDependency moduleDependency = (AbstractModuleDependency) parsed; - moduleDependency.setAttributesFactory(attributesFactory); - moduleDependency.setCapabilityNotationParser(capabilityNotationParser); - } - - return parsed; - } - - @Override - public void describe(DiagnosticsVisitor visitor) { - delegate.describe(visitor); - } - } - } diff --git a/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/catalog/LibrariesSourceGeneratorTest.groovy b/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/catalog/LibrariesSourceGeneratorTest.groovy index cb5a07971cef..ef1647ad0409 100644 --- a/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/catalog/LibrariesSourceGeneratorTest.groovy +++ b/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/catalog/LibrariesSourceGeneratorTest.groovy @@ -22,6 +22,9 @@ import org.gradle.api.InvalidUserDataException import org.gradle.api.internal.ClassPathRegistry import org.gradle.api.internal.DefaultClassPathProvider import org.gradle.api.internal.DefaultClassPathRegistry +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParserFactory +import org.gradle.api.internal.attributes.ImmutableAttributesFactory import org.gradle.api.internal.catalog.problems.VersionCatalogErrorMessages import org.gradle.api.internal.catalog.problems.VersionCatalogProblemId import org.gradle.api.internal.catalog.problems.VersionCatalogProblemTestFor @@ -40,6 +43,7 @@ import org.gradle.internal.management.VersionCatalogBuilderInternal import org.gradle.internal.service.scopes.Scopes import org.gradle.process.ExecOperations import org.gradle.test.fixtures.file.TestNameTestDirectoryProvider +import org.gradle.util.AttributeTestUtil import org.gradle.util.TestUtil import org.junit.Rule import spock.lang.Issue @@ -60,6 +64,8 @@ class LibrariesSourceGeneratorTest extends Specification implements VersionCatal private GeneratedSource sources final ObjectFactory objects = TestUtil.objectFactory() + final ImmutableAttributesFactory attributesFactory = AttributeTestUtil.attributesFactory() + final CapabilityNotationParser capabilityNotationParser = new CapabilityNotationParserFactory(false).create() final ProviderFactory providerFactory = new DefaultProviderFactory( new DefaultValueSourceProviderFactory( new DefaultListenerManager(Scopes.Build), @@ -406,7 +412,7 @@ ${nameClash { noIntro().kind('dependency bundles').inConflict('one.cool', 'oneCo def cl = new URLClassLoader([dstDir.toURI().toURL()] as URL[], this.class.classLoader) factory = cl.loadClass("org.test.$className") assert factory - factory.newInstance(model, providerFactory, objects) + factory.newInstance(model, providerFactory, objects, attributesFactory, capabilityNotationParser) } }