Upgrade to Spring Boot 3 and Kotlin 1.8

This commit is contained in:
Sébastien Deleuze
2023-01-09 11:35:54 +01:00
parent 37184766b5
commit 6c5f47a49f
6 changed files with 43 additions and 71 deletions

View File

@@ -82,11 +82,11 @@ In order to be able to use Kotlin non-nullable properties with JPA, https://kotl
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
kotlin("plugin.jpa") version "1.6.21" id("org.springframework.boot") version "3.0.1"
id("org.springframework.boot") version "2.7.1" id("io.spring.dependency-management") version "1.1.0"
id("io.spring.dependency-management") version "1.0.11.RELEASE" kotlin("jvm") version "1.8.0"
kotlin("jvm") version "1.6.21" kotlin("plugin.spring") version "1.8.0"
kotlin("plugin.spring") version "1.6.21" kotlin("plugin.jpa") version "1.8.0"
} }
---- ----
@@ -110,9 +110,8 @@ tasks.withType<KotlinCompile> {
=== Dependencies === Dependencies
3 Kotlin specific libraries are required for such Spring Boot web application and configured by default: 2 Kotlin specific libraries are required for such Spring Boot web application and configured by default:
- `kotlin-stdlib-jdk8` is the Java 8 variant of Kotlin standard library
- `kotlin-reflect` is Kotlin reflection library - `kotlin-reflect` is Kotlin reflection library
- `jackson-module-kotlin` adds support for serialization/deserialization of Kotlin classes and data classes (single constructor classes can be used automatically, and those with secondary constructors or static factories are also supported) - `jackson-module-kotlin` adds support for serialization/deserialization of Kotlin classes and data classes (single constructor classes can be used automatically, and those with secondary constructors or static factories are also supported)
@@ -125,7 +124,6 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
runtimeOnly("com.h2database:h2") runtimeOnly("com.h2database:h2")
runtimeOnly("org.springframework.boot:spring-boot-devtools") runtimeOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.boot:spring-boot-starter-test")
@@ -206,8 +204,8 @@ Notice also that Kotlin compiler is configured to generate Java 8 bytecode (Java
3 Kotlin specific libraries are required for such Spring Boot web application and configured by default: 3 Kotlin specific libraries are required for such Spring Boot web application and configured by default:
- `kotlin-stdlib-jdk8` is the Java 8 variant of Kotlin standard library - `kotlin-stdlib` is the Kotlin standard library
- `kotlin-reflect` is Kotlin reflection library (mandatory as of Spring Framework 5) - `kotlin-reflect` is Kotlin reflection library
- `jackson-module-kotlin` adds support for serialization/deserialization of Kotlin classes and data classes (single constructor classes can be used automatically, and those with secondary constructors or static factories are also supported) - `jackson-module-kotlin` adds support for serialization/deserialization of Kotlin classes and data classes (single constructor classes can be used automatically, and those with secondary constructors or static factories are also supported)
`pom.xml` `pom.xml`
@@ -236,7 +234,7 @@ Notice also that Kotlin compiler is configured to generate Java 8 bytecode (Java
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId> <artifactId>kotlin-stdlib</artifactId>
</dependency> </dependency>
<dependency> <dependency>
@@ -470,13 +468,13 @@ With Gradle:
---- ----
plugins { plugins {
... ...
kotlin("plugin.allopen") version "1.6.21" kotlin("plugin.allopen") version "1.8.0"
} }
allOpen { allOpen {
annotation("javax.persistence.Entity") annotation("jakarta.persistence.Entity")
annotation("javax.persistence.Embeddable") annotation("jakarta.persistence.Embeddable")
annotation("javax.persistence.MappedSuperclass") annotation("jakarta.persistence.MappedSuperclass")
} }
---- ----
@@ -495,9 +493,9 @@ Or with Maven:
<plugin>all-open</plugin> <plugin>all-open</plugin>
</compilerPlugins> </compilerPlugins>
<pluginOptions> <pluginOptions>
<option>all-open:annotation=javax.persistence.Entity</option> <option>all-open:annotation=jakarta.persistence.Entity</option>
<option>all-open:annotation=javax.persistence.Embeddable</option> <option>all-open:annotation=jakarta.persistence.Embeddable</option>
<option>all-open:annotation=javax.persistence.MappedSuperclass</option> <option>all-open:annotation=jakarta.persistence.MappedSuperclass</option>
</pluginOptions> </pluginOptions>
</configuration> </configuration>
</plugin> </plugin>
@@ -796,12 +794,11 @@ With Gradle:
[source,kotlin] [source,kotlin]
---- ----
testImplementation("org.springframework.boot:spring-boot-starter-test") { testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(module = "junit")
exclude(module = "mockito-core") exclude(module = "mockito-core")
} }
testImplementation("org.junit.jupiter:junit-jupiter-api") testImplementation("org.junit.jupiter:junit-jupiter-api")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testImplementation("com.ninja-squad:springmockk:3.0.1") testImplementation("com.ninja-squad:springmockk:4.0.0")
---- ----
Or with Maven: Or with Maven:
@@ -813,16 +810,6 @@ Or with Maven:
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
@@ -832,7 +819,7 @@ Or with Maven:
<dependency> <dependency>
<groupId>com.ninja-squad</groupId> <groupId>com.ninja-squad</groupId>
<artifactId>springmockk</artifactId> <artifactId>springmockk</artifactId>
<version>3.0.1</version> <version>4.0.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
---- ----
@@ -882,13 +869,11 @@ NOTE: `$` needs to be escaped in strings as it is used for string interpolation.
== Configuration properties == Configuration properties
In Kotlin, the recommended way to manage your application properties is to leverage `@ConfigurationProperties` with In Kotlin, the recommended way to manage your application properties is to use read-only properties.
`@ConstructorBinding` in order to be able to use read-only properties.
`src/main/kotlin/com/example/blog/BlogProperties.kt` `src/main/kotlin/com/example/blog/BlogProperties.kt`
[source,kotlin] [source,kotlin]
---- ----
@ConstructorBinding
@ConfigurationProperties("blog") @ConfigurationProperties("blog")
data class BlogProperties(var title: String, val banner: Banner) { data class BlogProperties(var title: String, val banner: Banner) {
data class Banner(val title: String? = null, val content: String) data class Banner(val title: String? = null, val content: String)
@@ -914,7 +899,7 @@ To generate https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle
---- ----
plugins { plugins {
... ...
kotlin("kapt") version "1.6.21" kotlin("kapt") version "1.8.0"
} }
dependencies { dependencies {

View File

@@ -1,18 +1,18 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
id("org.springframework.boot") version "2.7.1" id("org.springframework.boot") version "3.0.1"
id("io.spring.dependency-management") version "1.0.11.RELEASE" id("io.spring.dependency-management") version "1.1.0"
kotlin("jvm") version "1.6.21" kotlin("jvm") version "1.8.0"
kotlin("plugin.spring") version "1.6.21" kotlin("plugin.spring") version "1.8.0"
kotlin("plugin.allopen") version "1.6.21" kotlin("plugin.allopen") version "1.8.0"
kotlin("plugin.jpa") version "1.6.21" kotlin("plugin.jpa") version "1.8.0"
kotlin("kapt") version "1.6.21" kotlin("kapt") version "1.8.0"
} }
group = "com.example" group = "com.example"
version = "0.0.1-SNAPSHOT" version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8 java.sourceCompatibility = JavaVersion.VERSION_17
repositories { repositories {
mavenCentral() mavenCentral()
@@ -24,29 +24,28 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
runtimeOnly("com.h2database:h2") runtimeOnly("com.h2database:h2")
runtimeOnly("org.springframework.boot:spring-boot-devtools") runtimeOnly("org.springframework.boot:spring-boot-devtools")
kapt("org.springframework.boot:spring-boot-configuration-processor") kapt("org.springframework.boot:spring-boot-configuration-processor")
testImplementation("org.springframework.boot:spring-boot-starter-test") { testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
exclude(module = "mockito-core") exclude(module = "mockito-core")
} }
testImplementation("org.junit.jupiter:junit-jupiter-api") testImplementation("org.junit.jupiter:junit-jupiter-api")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testImplementation("com.ninja-squad:springmockk:3.1.1") testImplementation("com.ninja-squad:springmockk:4.0.0")
} }
tasks.withType<KotlinCompile> { tasks.withType<KotlinCompile> {
kotlinOptions { kotlinOptions {
jvmTarget = "17"
freeCompilerArgs += "-Xjsr305=strict" freeCompilerArgs += "-Xjsr305=strict"
} }
} }
allOpen { allOpen {
annotation("javax.persistence.Entity") annotation("jakarta.persistence.Entity")
annotation("javax.persistence.Embeddable") annotation("jakarta.persistence.Embeddable")
annotation("javax.persistence.MappedSuperclass") annotation("jakarta.persistence.MappedSuperclass")
} }
tasks.withType<Test> { tasks.withType<Test> {

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

26
pom.xml
View File

@@ -14,15 +14,15 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version> <version>3.0.1</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>17</java.version>
<kotlin.version>1.6.21</kotlin.version> <kotlin.version>1.8.0</kotlin.version>
</properties> </properties>
<dependencies> <dependencies>
@@ -44,7 +44,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId> <artifactId>kotlin-stdlib</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
@@ -65,16 +65,6 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
@@ -84,7 +74,7 @@
<dependency> <dependency>
<groupId>com.ninja-squad</groupId> <groupId>com.ninja-squad</groupId>
<artifactId>springmockk</artifactId> <artifactId>springmockk</artifactId>
<version>3.1.1</version> <version>4.0.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
@@ -110,9 +100,9 @@
<plugin>all-open</plugin> <plugin>all-open</plugin>
</compilerPlugins> </compilerPlugins>
<pluginOptions> <pluginOptions>
<option>all-open:annotation=javax.persistence.Entity</option> <option>all-open:annotation=jakarta.persistence.Entity</option>
<option>all-open:annotation=javax.persistence.Embeddable</option> <option>all-open:annotation=jakarta.persistence.Embeddable</option>
<option>all-open:annotation=javax.persistence.MappedSuperclass</option> <option>all-open:annotation=jakarta.persistence.MappedSuperclass</option>
</pluginOptions> </pluginOptions>
</configuration> </configuration>
<dependencies> <dependencies>

View File

@@ -1,9 +1,7 @@
package com.example.blog package com.example.blog
import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding
@ConstructorBinding
@ConfigurationProperties("blog") @ConfigurationProperties("blog")
data class BlogProperties(var title: String, val banner: Banner) { data class BlogProperties(var title: String, val banner: Banner) {
data class Banner(val title: String? = null, val content: String) data class Banner(val title: String? = null, val content: String)

View File

@@ -1,7 +1,7 @@
package com.example.blog package com.example.blog
import java.time.LocalDateTime import java.time.LocalDateTime
import javax.persistence.* import jakarta.persistence.*
@Entity @Entity
class Article( class Article(