Hi!
Spring-boot-gradle plugin creates bootJar task only when java plugin is applied (https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/#packaging-executable.jars).
Executable jars can be built using the bootJar task. The task is automatically created when the java plugin is applied and is an instance of BootJar.
However, it is not required as other JVM languages can apply just java-base plugin to enable java-ecosystem support in Gradle.
This is now the case for Kotlin Multiplatform Gradle Plugin as it stopped applying java plugin since 1.9.20 release.
plugins {
id("java") // is required since Kotlin 1.9.20!
id("org.springframework.boot") version "3.1.5"
id("io.spring.dependency-management") version "1.1.3"
id 'org.jetbrains.kotlin.multiplatform' version '1.9.20'
}
bootJar { // without applying java plugin this extension will not be available
}
The current workaround for users is to apply java plugin explicitly. But I don't think they have to do so in order to use bootJar.
Would you consider creating bootJar upon java-base plugin application instead java one?
NB: java plugin is applying java-base inside so other users will not be affected.
You can read this article for reference https://docs.gradle.org/current/userguide/designing_gradle_plugins.html#capabilities-vs-conventions
Here is related Kotlin issue that was reported as part of this problem: https://youtrack.jetbrains.com/issue/KT-63083/KMP-Spring-Could-not-find-method-bootJar-with-1.9.20
Comment From: wilkinsona
Thanks for the suggestion but I don't think we can switch to reacting to java-base being applied.
The bootJar task relies on many of the conventions that are set up by the java plugin. For example, with only the java-base plugin applied, there's no main source set. We use the main source set to determine the classes, resources, and dependencies that should be packaged in the uber jar that bootJar produces.
Perhaps org.jetbrains.kotlin.multiplatform also sets up a source set named main? If so, we could perhaps react to that in a somewhat similar way to what we do for java being applied.
NB: java plugin is applying java-base inside so other users will not be affected.
I think that other users may be affected. If they're applying Boot's plugin and java-base today they may be relying on Boot's plugin not doing very much and then configuring things manually.
Comment From: antohaby
Thanks for the quick reaction!
The bootJar task relies on many of the conventions that are set up by the java plugin. For example, with only the java-base plugin applied, there's no main source set. We use the main source set to determine the classes, resources, and dependencies that should be packaged in the uber jar that bootJar produces.
Then it is fair to depend on java plugin. It should work well with just Kotlin Gradle Plugin for JVM as this plugin also integrates with java. However, Multiplatform users wouls need to configure bootJar themselves.
Because Kotlin Multiplatform Gradle Plugin doesn't use default entities such as main source set and configurations (api, implementation, classpath, etc) it uses its own prefixed entities.
In order to use bootJar inside Kotlin Multiplatform Gradle Plugin user would need to do something like this:
tasks.bootJar {
val runtimeClasspath = kotlin.jvm().compilations.getByName("main").runtimeDependencyFiles
val developmentOnly = project.configurations
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME)
val productionRuntimeClasspath = project.configurations
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_CONFIGURATION_NAME)
val classpath = runtimeClasspath
.minus(developmentOnly.minus(productionRuntimeClasspath))
// TODO: add JarTypeFileSpec filter
this.classpath(classpath)
if (runtimeClasspath is Configuration) {
this.resolvedArtifacts(runtimeClasspath.incoming.artifacts.resolvedArtifacts)
}
}
I'm not sure if there any plugins (in community or inside spring-boot projects) that aim to support Kotlin Multiplatform Gradle Plugin. In this case we (as Kotlin Team) would be happy to consult them about such integration with Spring Boot Gradle Plugin.
I believe this issue can be closed then.
Comment From: wilkinsona
I'm not sure if there any plugins (in community or inside spring-boot projects) that aim to support Kotlin Multiplatform Gradle Plugin. In this case we (as Kotlin Team) would be happy to consult them about such integration with Spring Boot Gradle Plugin.
Thanks for the offer. We don't have any plans for this at the moment but we will reach out if there's demand for it in the future.