<spring initializer> creates the following build.g...
# spring
p
spring initializer creates the following build.gradle.kts:
Copy code
plugins {
  id("org.springframework.boot") version "3.3.0"
  id("io.spring.dependency-management") version "1.1.5"
  kotlin("jvm") version "1.9.24"
  kotlin("plugin.spring") version "1.9.24"
}
...
The
kotlin("jvm")
value is the kotlin version? Should it be equal to
plugin.spring
version? I do not know much about build.gradle(.kts), is there a basic article about the basics? Can I upgrade and use kotlin 2.0?
👌 2
r
It's good to also add:
Copy code
extra["kotlin.version"] = "2.0.0"
👍 1
p
Cannot I specify in one place my desired kotlin version?
r
You can, but you need to use different project layout (e.g. using version catalog https://medium.com/@callmeryan/gradle-version-catalog-728111fa210f)
t
how we do is in
gradle.properties
Copy code
kotlin_version=2.0.0
# Spring Boot overrides
kotlin.version=${kotlin_version}
and in
build.gradle
(but should work similarly for kts file)
Copy code
plugins {
  id "org.jetbrains.kotlin.jvm" version "$kotlin_version"
  //etc
}
👍 1
k
By the way,
kotlin(module: String)
is just a convenience function that returns
id("org.jetbrains.kotlin.$module")
. That's good to know when you look at various example build.gradle.kts files and wonder why some use the
kotlin
function and others don't.
😮 1
> is there a basic article about the basics? I hope someone can supply a useful link, but from my experience there's nothing "basic" about Gradle: the gradle.org website has a lot of documentation but when you look at the build file of a fully grown Gradle project and try to understand it, you'll find that you'll need to read almost all of the extensive documentation, and then you'll learn that various features quickly get deprecated with new versions, and that there are dozens of different (and incompatible) ways of doing the same thing.
📚 1
😮‍💨 1
thank you color 2
p
Copy code
# Spring Boot overrides
Could you tell me about that override, @thanksforallthefish ?
t
spring boot dependencies are managed by the dependency management plugin, but you can override those dependencies in your config files. https://docs.spring.io/spring-boot/appendix/dependency-versions/coordinates.html presents the list of managed dependencies and their versions, https://docs.spring.io/spring-boot/appendix/dependency-versions/properties.html presents the property you can define to override the default version, either in
gradle.propertie
or in
extra
(as Robert was pointing out). I think there are also other ways to define those properties, but honestly 2 is already one-too-many for my taste
👍 1
p
So, having a
gradle.properties
in project root with content
Copy code
kotlin_version=2.0.0
# Spring Boot overrides
kotlin.version=${kotlin_version}
and after that, in
build.gradle.kts
Copy code
kotlin("jvm") version "$kotlin_version"
kotlin("plugin.spring") version "$kotlin_version"

// allows all Kotlin classes in a project to be open for subclassing by default.
kotlin("plugin.allopen") version "$kotlin_version"
kotlin("plugin.jpa") version "$kotlin_version"
I get
Copy code
* What went wrong:
Script compilation errors:

  Line 12:     kotlin("jvm") version "$kotlin_version"
                                       ^ Unresolved reference: kotlin_version

  Line 13:     kotlin("plugin.spring") version "$kotlin_version"
                                                 ^ Unresolved reference: kotlin_version

  Line 16:     kotlin("plugin.allopen") version "$kotlin_version"
                                                  ^ Unresolved reference: kotlin_version

  Line 17:     kotlin("plugin.jpa") version "$kotlin_version"
                                              ^ Unresolved reference: kotlin_version
k
This is happening because what you've defined as
kotlin_version
and
kotlin.version
are project properties, but the Kotlin DSL in your build file expects
kotlin_version
to be a Kotlin
String
variable. You can put this:
Copy code
val kotlin_version: String by project
at the top of your build.gradle.kts file.
By the way, you don't need the
allopen
plugin if you already have the
spring
plugin. Also, the plugins need to go in the
plugins
section, not the
dependencies
section where your
kotlin("jvm")
is.
thank you color 1
p
So: gradle.properties
Copy code
kotlin_version=2.0.0
# Spring Boot overrides
kotlin.version=${kotlin_version}
extra["kotlin_version"]="2.0.0"
build.gradle.kts
Copy code
import java.util.*

val kotlin_version: String by project

group = "xxxxxx"
version = Properties().apply { load(file("build.properties").inputStream()) }.getProperty("VERSION")

plugins {
    id("org.springframework.boot") version "3.0.4"
    id("io.spring.dependency-management") version "1.1.0"
    id("jacoco")
    id("org.sonarqube") version "3.3"
    kotlin("jvm") version kotlin_version
    kotlin("plugin.spring") version kotlin_version
    kotlin("plugin.jpa") version kotlin_version
but still getting the same error.
IDE hint: 'val kotlin_version: String' can't be called in this context by implicit receiver. Use the explicit one if necessary
k
Ah, I just realised I misled you a bit. You can use the
val kotlin_version
inside your
dependencies
block (which is where you should define
kotlin("jvm")
, not in your plugins block). However, the
plugins
block unfortunately has restrictions which means you can't use this
val
inside the
plugins
block.
😮 1
t
tbh I don't know if it is a difference between groovy
GString
and kotlin string, but in groovy-gradle you can do
Copy code
plugins {
  id "org.jetbrains.kotlin.jvm" version "$kotlin_version"
}
however you cannot do
Copy code
plugins {
  id "org.jetbrains.kotlin.jvm" version kotlin_version
}
note:
kotlin_version
defined in
gradle.properties
. it's true the docs say
Where «plugin id» and «plugin version» must be constant, literal strings.
though personally I haven't made the switch to kotlin-gradle yet, last time I tried it was too slow, though I think it was at least a couple of years ago and in the meantime a lot of improvements happened
it seems kotlin needs an extra step in
settings
file: https://github.com/gradle/gradle/issues/1697#issuecomment-655682357
Copy code
//gradle.properties
kotlinVersion=2.0.0
kotlin.version=${kotlin_version}

// settings.gradle.kts:
pluginManagement {
    val kotlinVersion: String by extra
    plugins {
        id("org.jetbrains.kotlin.jvm").version(kotlinVersion)
    }
}

//build.gradle.kts
plugins {
    // Apply plugins without versions:
    id("org.jetbrains.kotlin.jvm")
}
k
I told you Gradle was complicated, didn't I? 😉
p
I hoped in the past, that kotlin dsl is a bit simpler, but seem it has so many dependencies, that I continue to avoid any contact with gradle 😢
t
I like gradle more than maven by a mile, but it's true that it's complicated, and the 2 dsl, and the freedom coming from the possibility of doing things in multiple ways (and I think declarative gradle was announced recently, https://declarative.gradle.org/docs/getting-started/) don't make for an easy experience