spring-boot icon indicating copy to clipboard operation
spring-boot copied to clipboard

SpringBoot plugin uses wrong task type for 'createStartScripts' inherits wrong class

Open cpuzicha opened this issue 1 year ago • 1 comments

Output from my own plugin test, built with Gradle 8.6: The task 'bootStartScripts' (org.gradle.jvm.application.tasks.CreateStartScripts) is not a subclass of the given type (org.gradle.api.tasks.application.CreateStartScripts)

Shouldn't custom tasks prefer the API versions of tasks? org.gradle.api.tasks.application.CreateStartScripts extends org.gradle.jvm.application.tasks.CreateStartScripts anyway.

cpuzicha avatar Feb 15 '24 09:02 cpuzicha

@cpuzicha Do you have a way for us to replicate the "The task 'bootStartScripts' (org.gradle.jvm.application.tasks.CreateStartScripts) is not a subclass of the given type (org.gradle.api.tasks.application.CreateStartScripts)" error?

I'm not sure we've seen it in our own tests.

philwebb avatar Feb 15 '24 17:02 philwebb

File: build.gradle.kts

plugins {
    id("java")
    id("application")
    id("org.springframework.boot") version "3.2.2"
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

tasks.withType(CreateStartScripts::class).forEach {
    logger.lifecycle("Found start script task: ${it.name}")
}

tasks.named("bootStartScripts").get().let {
    logger.lifecycle("${it.name} has class ${it::class.qualifiedName}")
}

tasks.named("bootStartScripts", CreateStartScripts::class) {
    //fails
}

cpuzicha avatar Feb 19 '24 07:02 cpuzicha

sb-39584.zip

Here's one which we can unzip and use.

mhalbritter avatar Feb 19 '24 10:02 mhalbritter

If I change in org.springframework.boot.gradle.plugin.ApplicationPluginAction

import org.gradle.jvm.application.tasks.CreateStartScripts;

to

import org.gradle.api.tasks.application.CreateStartScripts;

our build still works.

However I lack the Gradle knowledge to determine if this is the right thing to do.

mhalbritter avatar Feb 19 '24 10:02 mhalbritter

It could be argued that this is user error as it's making an assumption about the type of the bootStartScripts task that doesn't hold true. This should work:

tasks.named("bootStartScripts", org.gradle.jvm.application.tasks.CreateStartScripts::class) {
    // works?
}

That said, I don't think there's any good reason for us to be using org.gradle.jvm.application.tasks.CreateStartScripts rather than org.gradle.api.tasks.application.CreateStartScripts. I suspect it's just an accident of auto-completion when I worked on https://github.com/spring-projects/spring-boot/issues/20759 and perhaps a hangover from https://github.com/spring-projects/spring-boot/issues/2622.

Given that Gradle implicitly imports the org.gradle.api.tasks.* classes into your build script, there is a good reason for us to be using org.gradle.api.tasks.application.CreateStartScripts. Furthermore, org.gradle.api.tasks.application.CreateStartScripts is a subclass of org.gradle.jvm.application.tasks.CreateStartScripts. I think it's very unlikely that anyone has written a build the relies upon bootStartScripts specifically being an instance of org.gradle.jvm.application.tasks.CreateStartScripts so I think we can safely change to org.gradle.api.tasks.application.CreateStartScripts as a bug fix in 3.1.x.

wilkinsona avatar Feb 21 '24 11:02 wilkinsona

Even if they did, the .api class extends the .jvm class

cpuzicha avatar Feb 22 '24 08:02 cpuzicha

Any reason this is added to 3.1.x but not to 3.2.x and most importantly the main branch?

cpuzicha avatar Feb 23 '24 15:02 cpuzicha

We fix in the oldest affected branch and then merge forwards. The fix will land in 3.1.x and then be merged forwards into 3.2.x and then main.

wilkinsona avatar Feb 23 '24 15:02 wilkinsona