reckon: NPE: Must provide a scope supplier

Hello and thanks for reckon. Been using it for a while and it really really helps managing versions.

On some project, I’m trying to upgrade kotlin JVM plugin from 1.3.72 to 1.4.10 and get the following error:

* What went wrong:
Failed to apply plugin [id 'org.jetbrains.kotlin.jvm']
> Must provide a scope supplier.

I probably did something wrong, but everything was working completely fine with 1.3.72, any idea?

Thanks a lot.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 2
  • Comments: 19 (5 by maintainers)

Most upvoted comments

@aesteve I had the same issue in a multi-project build. For me, the issue was that the subprojects block was located (on gradle.build), before the reckon {} block, and apparently the kotlin plugin now needs access to project.version, before reckon is ready to provide it. This seem to match the situation on this test

I was able to fix it just by moving the reckon configuration block right below the plugins {} block, before subprojects

Hey @aesteve I solved the problem by reordering the plugins:

    kotlin("jvm") version "1.4.10"
    kotlin("plugin.jpa") version "1.4.10"
    kotlin("plugin.spring") version "1.4.10"
    kotlin("kapt") version "1.4.10"
    id("org.ajoberstar.reckon") version "0.13.0"

More specifically I put the reckon plugin after kotlin plugins.

Re: @x80486 in #170 (which is a duplicate of this discussion)

Do you think there could be a resolution for this or would it be like that because the issue with the plugins block?

I do have other plugins in use and as soon as I start using the apply plugin way (even with Reckon only), they start failing as well; for instance, this is one of them: com.github.jakemarsden.git-hooks — unable to get the version number.

I guess it’s around the same subject all this.

I have a handful of thoughts around this:

  1. If reckon could configure the version even earlier, it could be done in time for other plugins that “behave badly” in toStringing version eagerly to not notice. This could maybe be done with a Plugin<Settings>, which aren’t common and I’ve not used before, but should be early enough to stop any normal Plugin<Project> from interfering. It would also reinforce the idea that reckon is setting a build-wide version not a project-specific version.
  2. Reckon could be a little more forgiving. If you haven’t configured the reckon block yet, but something needed the version, just return “unspecified” or whatever the default version is, log a warning to the console, and let someone try again later. Currently, it’s trying to be safe in the sense that if you wanted reckon involved you wanted its version to be used. If something is calling version.toString() before the reckon {} has run its going to get the wrong version regardless, because it’s probably running before the user had a change to write version = 'whatever' if they weren’t using reckon. Maybe that caller doesn’t need the version for an important purpose or maybe the plugin or you will go correct it later anyway. However, that’s utlimately a problem with the other plugin, and not something reckon really needs to play traffic cop on. The logging should help trace down the offending plugin in case tweaks need to be made there.
  3. Gradle could make the implicit laziness of project.getVersion() explicit by using Property<String>. They have issues open for this in gradle/gradle#13672 and gradle/gradle#15088. Even if they fix this, it will take time for plugins to be updated to use the new method. Since plugins could address this currently anyway, it doesn’t replace the need for 1 or 2.
  4. I’ve seen another case of this error happen where it was actually covering up a different problem. Another failure was happening, but somehow in the chain it needed to access the version, and the reckon exception buried the real problem. Usually in this case, disabling reckon would help you see the real exception. Not applicable to all cases.
  5. Ultimately, the other plugins need to reckon with (pun intended) how they use project.getVersion() and likely make changes to access it more lazily. Again 3 would help them with this, but its not necessary technically.

I’m currently working on updates to other plugins, so this isn’t the top of my list, but I do plan to come back to this. And I think both 1 and 2 are approaches I want to pursue.

The general problem here is likely other plugins that are too eagerly trying to get the version from project.getVersion().toString(). Reckon’s approach is only quasi-supported by Gradle by them declaring the type of project.getVersion() as Object instead of String. Nowadays it should really be a Provider<String> which would work better with how Reckon wants to behave.

I’m not sure if it’s resolvable by Reckon, since it almost looks like a plugin trying to access the version before the reckon {} extension block runs, which really seems like a bug in another plugin. I could be misinterpreting here though.

I would be curious if 0.14.0 works any better for those of you with this issue. The fundamental approach is unchanged, but it more deeply uses BuildService and Property/Provider that before.

Hmm, maybe #170 is duplicate but it only started happening for me after a Gradle 7.4 upgrade, with jacoco.

I have no idea how determinate it is in Gradle; but just changing the order in the plugins block seemed enough to go from working to broken. 😬

I have the same issue here but with a normal java project. This is with a project using the java-test-fixtures plugin.

I am experiencing the same issue! I am using (among others) these plugins:

kotlin("jvm") version "1.3.72"
kotlin("plugin.jpa") version "1.3.72"
kotlin("plugin.spring") version "1.3.72"
kotlin("kapt") version "1.3.72"

When I switch to version 1.4.0 upon reimport of gradle projects I get this weird exception

org.gradle.api.ProjectConfigurationException: A problem occurred configuring root project '<name-of-the-project>'. 
Caused by: java.util.NoSuchElementException: Collection is empty.
	at kotlin.collections.CollectionsKt___CollectionsKt.single(_Collections.kt:534)
	at org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinTarget.sourcesJarArtifact(kotlinTargets.kt:200)
	at org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinTarget.sourcesJarArtifact$default(kotlinTargets.kt:188)
	at org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinTarget$kotlinComponents$2.invoke(kotlinTargets.kt:78)
	at org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinTarget$kotlinComponents$2.invoke(kotlinTargets.kt:36)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinTarget.getKotlinComponents$kotlin_gradle_plugin(kotlinTargets.kt)
	at org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPluginKt$applyUserDefinedAttributes$1.invoke(KotlinMultiplatformPlugin.kt:320)
	at org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPluginKt$applyUserDefinedAttributes$1.invoke(KotlinMultiplatformPlugin.kt)
	at org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginKt$whenEvaluated$1.execute(KotlinMultiplatformPlugin.kt:213)
	at org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginKt$whenEvaluated$1.execute(KotlinMultiplatformPlugin.kt)

When I try to gradle clean or build I get the already mentioned exception:

An exception occurred applying plugin request [id: 'org.jetbrains.kotlin.jvm', version: '1.4.0']
> Failed to apply plugin 'org.jetbrains.kotlin.jvm'.
   > Must provide a scope supplier.

Could you guys have a look? We would like to use some features of 1.4.0.

Relevant (maybe) info:

  • that’s a multi-module Kotlin project
  • reckon is configured in the root project as follows:
// Root Project
apply(plugin = "org.ajoberstar.reckon")

reckon {
    scopeFromProp()
    stageFromProp("milestone", "rc", "final")
}