Hi, i have a kotlin multiplatform multi module project setup where the mutiplatform plugin and it’s ...
s
Hi, i have a kotlin multiplatform multi module project setup where the mutiplatform plugin and it’s configurations are extracted as a pre-compiled script plugin in build-logic composite build. In each module, i will apply that plugin and add more dependencies as required for that corresponding module. This is working fine for “kotlin-jvm”, but when i do the same thing for “multiplatform”, getting the following error
Copy code
* What went wrong:
An exception occurred applying plugin request [id: 'plugins.kotlinMPP']
> Failed to apply plugin 'plugins.kotlinMPP'.
   > Configuration already finalized for previous property values
Any hints on how to fix this or any other recommended approach to use it as convention plugin?
Here is the plugin config applied in the module
Copy code
// this is my pre-compile script plugin, which configures default mpp target and dependencies

plugins { id("plugins.kotlinMPP") }

kotlin {
  sourceSets {
    val jsMain by getting { dependencies { implementation(projects.common) } }
  }
}
t
pasting the stacktrace could be helpful
s
Copy code
* Exception is:
org.gradle.api.plugins.InvalidPluginException: An exception occurred applying plugin request [id: 'plugins.kotlinMPP']
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.exceptionOccurred(DefaultPluginRequestApplicator.java:222)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugin(DefaultPluginRequestApplicator.java:204)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugin(DefaultPluginRequestApplicator.java:146)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.access$200(DefaultPluginRequestApplicator.java:60)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator$1$1.lambda$add$1(DefaultPluginRequestApplicator.java:119)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.lambda$applyPlugins$0(DefaultPluginRequestApplicator.java:142)
        at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugins(DefaultPluginRequestApplicator.java:142)
        at org.gradle.kotlin.dsl.provider.PluginRequestsHandler.handle(PluginRequestsHandler.kt:48)
        at org.gradle.kotlin.dsl.provider.StandardKotlinScriptEvaluator$InterpreterHost.applyPluginsTo(KotlinScriptEvaluator.kt:212)
        at org.gradle.kotlin.dsl.execution.Interpreter$ProgramHost.applyPluginsTo(Interpreter.kt:382)
        at Program.execute(Unknown Source)
        at org.gradle.kotlin.dsl.execution.Interpreter$ProgramHost.eval(Interpreter.kt:512)
        at org.gradle.kotlin.dsl.execution.Interpreter.eval(Interpreter.kt:210)
        at org.gradle.kotlin.dsl.provider.StandardKotlinScriptEvaluator.evaluate(KotlinScriptEvaluator.kt:119)
        at org.gradle.kotlin.dsl.provider.KotlinScriptPluginFactory$create$1.invoke(KotlinScriptPluginFactory.kt:51)
        at org.gradle.kotlin.dsl.provider.KotlinScriptPluginFactory$create$1.invoke(KotlinScriptPluginFactory.kt:48)
        at org.gradle.kotlin.dsl.provider.KotlinScriptPlugin.apply(KotlinScriptPlugin.kt:35)
        at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:65)
Copy code
Caused by: java.lang.IllegalStateException: Configuration already finalized for previous property values
        at org.jetbrains.kotlin.gradle.internal.ConfigurationPhaseAware.requireNotConfigured(ConfigurationPhaseAware.kt:24)
        at org.jetbrains.kotlin.gradle.internal.ConfigurationPhaseAware$Property.setValue(ConfigurationPhaseAware.kt:31)
        at org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension.setDownload(NodeJsRootExtension.kt:58)
        at plugins.KotlinMPP_gradle$$$result$1$1.invoke(kotlinMPP.gradle.kts:194)
        at plugins.KotlinMPP_gradle$$$result$1$1.invoke(kotlinMPP.gradle.kts:194)
        at plugins.KotlinMPP_gradle$inlined$sam$i$org_gradle_api_Action$0.execute(DomainObjectCollectionExtensions.kt)
i think the following config in the pre-compiled plugin causing the issues
Copy code
rootProject.plugins.withType<NodeJsRootPlugin> {
  rootProject.extensions.configure<NodeJsRootExtension> { download = true }
}

rootProject.plugins.withType<YarnPlugin> {
  rootProject.extensions.configure<YarnRootExtension> {
    download = true
    lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store")
  }
}
the plugin is getting applied to both common and web modules and causing issues
removing
rootProject.
solved the issue. But i am not sure if it has any other impact 🙂
removing rootProject is not working as expected. The current workaround is, use a conditional logic inside the convention plugin to execute the NodeJsRootExtension config only once in a jvm invocation
Something like
Copy code
var nodeExtnConfigured = System.getProperty("nodeExtnConfigured").toBoolean()

if (!nodeExtnConfigured) {
  // <https://kotlinlang.org/docs/js-project-setup.html#use-pre-installed-node-js>
  rootProject.plugins.withType<NodeJsRootPlugin> {
    rootProject.extensions.configure<NodeJsRootExtension> {
      download = true
      System.setProperty("nodeExtnConfigured", "true")
    }
  }

  // <https://kotlinlang.org/docs/js-project-setup.html#version-locking-via-kotlin-js-store>
  rootProject.plugins.withType<YarnPlugin> {
    rootProject.extensions.configure<YarnRootExtension> {
      download = true
      lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store")
      System.setProperty("nodeExtnConfigured", "true")
    }
  }
}