Could not get extension property outside gradle task (developing custom gradle plugin)

Greetings,

I am developing gradle plugin which adds some dependencies and I’d like to pass versions through extension property, so I have the following extension:

public class CustomVersionExtension
{
final Property someDependencyVersion;

public CustomVersionExtension(ObjectFactory objects)
{
	someDependencyVersion = objects.property(String.class);
}

public Property<String> getSomeDependencyVersion()
{
	return someDependencyVersion;
}

}

Configuration in build.gradle of project which uses this plugin:

customVersion {
someDependencyVersion.set(‘3.+’)
}

And code of plugin:

@Override
public void apply(Project project)
{
	CustomVersionExtension customVersionExtension = project.getExtensions().create("customVersion",
			CustomVersionExtension.class);

	project.getPlugins().withType(JavaPlugin.class, javaPlugin -> {
		JavaPluginConvention javaConvention = project.getConvention().getPlugin(JavaPluginConvention.class);

		SourceSetContainer sourceSets = javaConvention.getSourceSets();
		SourceSet testSourceSet = sourceSets.named(SourceSet.TEST_SOURCE_SET_NAME).get();

		SourceSet testApiSourceSet = sourceSets.register("testApi", sourceSet -> {
			SourceSet mainSourceSet = sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME).get();
			FileCollection mainAndTestOutput = mainSourceSet.getOutput().plus(testSourceSet.getOutput());
			sourceSet.setCompileClasspath(sourceSet.getCompileClasspath().plus(mainAndTestOutput));
			sourceSet.setRuntimeClasspath(sourceSet.getRuntimeClasspath().plus(mainAndTestOutput));
		}).get();

		// Cannot query the value of extension 'customVersion' property 'someDependencyVersion' because it has no value available
        // String versionOutside = customVersionExtension.getSomeDependencyVersion().get();

		ConfigurationContainer configurations = project.getConfigurations();
		configurations.named(testApiSourceSet.getImplementationConfigurationName()).configure(configuration -> {
			configuration.extendsFrom(
					configurations.named(testSourceSet.getImplementationConfigurationName()).get());
			configuration.getDependencies().add(
					project.getDependencies()
							.create("org.apache.commons:commons-lang3:" + "3.+"));
		});
		configurations.named(testApiSourceSet.getRuntimeOnlyConfigurationName()).configure(configuration ->
				configuration
						.extendsFrom(configurations.named(testSourceSet.getRuntimeOnlyConfigurationName()).get()));

		project.getTasks().register("testApi", Test.class, apiTest -> {
			apiTest.setGroup(JavaBasePlugin.VERIFICATION_GROUP);
			apiTest.setTestClassesDirs(testApiSourceSet.getOutput().getClassesDirs());
			apiTest.setClasspath(testApiSourceSet.getRuntimeClasspath());
			apiTest.useJUnitPlatform();

			String versionInside = customVersionExtension.getSomeDependencyVersion().get(); //3.+

			System.out.println(versionInside);
		});
	});
}

versionOutside - ‘Cannot query the value of extension ‘customVersion’ property ‘someDependencyVersion’ because it has no value available’, but version inside - have correct value. Is it possible to get extension properties outside task closure?

dependency-sample.zip (64.4 KB)
dependency-sample-plugin.zip (90.0 KB)

Your problem is that you try to evaluate the property too soon.
Your querycode is executed before the project build script had a chance to set it.
The lambda that you give to the tasks.register is only evaluated when the task is needed and as late as possible.
This is then after the build script had a chance to set the value and so you can query it.

1 Like

Thanks a lot. I put my code into project.afterEvaluate { } block and now I am able to get property value.