node-gradle / gradle-node-plugin

Gradle plugin for integrating NodeJS in your build. :rocket:
Apache License 2.0
601 stars 117 forks source link

YarnSetup StackOverflow When Using Gradle Kotlin DSL #248

Closed danielshiplett closed 1 year ago

danielshiplett commented 1 year ago

I'm having trouble using the plugin when I write my Gradle configurations using the Kotlin DSL. NodeSetup & NpmSetup seem to work and download/install the correct tools. However, the YarnSetup fails with a stack overflow:

$ gradle --stacktrace yarnSetup

FAILURE: Build failed with an exception.

* What went wrong:
java.lang.StackOverflowError (no error message)

* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Exception is:
java.lang.StackOverflowError
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:174)
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:178)
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:178)
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:178)
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:178)
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:178)
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:178)
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:178)
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:178)
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:178)
        at org.gradle.api.internal.provider.AbstractProperty.getProducer(AbstractProperty.java:178)

This behavior is consistent for all types of YarnTask (and also PnpmTask).

However, the same basic project setup using the Groovy DSL works fine.

Here is an example project that shows the failure: https://github.com/danielshiplett/node-plugin-error

This is a basic Kotlin application created by the Spring Initializer with a React application created in the 'frontend' directory. We've successfully used this pattern using Groovy for quite a while and wanted to switch our Gradle configurations over to Kotlin DSL as we are writing all our Spring applications in Kotlin now and it seemed more natural. However, the inability to use this plugin in the Kotlin DSL is blocking us from completing our conversions.

Please let me know if you need any more details or if I can help with testing.

deepy commented 1 year ago

On the bright side, this is very easy to reproduce:

plugins {
    id("com.github.node-gradle.node") version "3.4.0"
}

val yarnVersion = "1.22.19"

node {
    yarnVersion.set(yarnVersion)
}

You can work around it by using yarnVersion.set("1.22.19"). This may be related to the unorthodox way NodeExtension has been wired and if so that's unfortunately not a quick fix (although it's a good fix). But I'll do some more investigation tomorrow and I'm going to add tests to make sure we don't break kotlin scripts again.

danielshiplett commented 1 year ago

Oh dang! I never even thought to try that!

That works. Thanks so much. Looking forward to the long term solution. But this works for now.

deepy commented 1 year ago

After a cup of coffee there's a much easier solution to this šŸ˜³ But what you're seeing is that yarnVersion.set(yarnVersion) refers to itself as it's inside node {} so either switching to node.yarnVersion.set(yarnVersion) or renaming yarnVersion to something else will solve this

danielshiplett commented 1 year ago

Oh double dang!!

Good catch. I wouldn't have thought of that either.

Turns out in the Groovy variant of my project, it was defined in the extras block and used as 'property.yarnVersion'. Renaming the val in Kotlin was enough to fix it so I'm just going to skip the extra extension.

Thanks for finding this for me!