Spring boot - Cannot subclass final class - spring-boot

I'm writing a back end in spring boot. I'm not sure if I've updated a package or what but after a few months of dev, suddenly I got this error on some of my controllers:
Error creating bean with name 'authApi' defined in file ... Cannot subclass final class
I've googled it and found some explanations of why Spring Boot need classes to be open so I was ready to mark all my classes as open but then my auto-wired constructor parameters and properties initialised in place are all null.
Here is an example controller:
#RestController
#RequestMapping("/api")
open class AuthApi(
private val userManager: UserManager,
private val authenticationManager: AuthenticationManager,
private val jwtEncoder: JwtEncoder
){
val logger = LoggerFactory.getLogger(AuthApi::class.java)
}
Here are my Gradle files. The issue appeared after I've updated the two submodule's Gradle files to disable bootJar. I'm not sure how that could affect the situation but maybe I've cleared some kind of cache and "triggered" an issue I've caused earlyer
Main:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import com.github.gradle.node.yarn.task.YarnTask
buildscript{
repositories {
maven {
url = uri("https://plugins.gradle.org/m2/")
}
}
dependencies{
classpath("com.github.node-gradle:gradle-node-plugin:3.2.1")
}
}
plugins {
id("org.springframework.boot") version "2.7.8"
id("io.spring.dependency-management") version "1.1.0"
kotlin("jvm") version "1.6.10"
kotlin("plugin.spring") version "1.6.10"
kotlin("plugin.jpa") version "1.5.21"
id("com.github.node-gradle.node") version "3.2.1"
}
allprojects {
apply(plugin = "io.spring.dependency-management")
apply(plugin = "org.springframework.boot")
apply(plugin = "com.github.node-gradle.node")
apply(plugin = "java")
apply(plugin = "kotlin")
group = "com.test"
version = "0.9.0"
java.sourceCompatibility = JavaVersion.VERSION_17
repositories {
mavenCentral()
}
}
subprojects {
apply(plugin = "java")
apply(plugin = "kotlin")
apply(plugin="io.spring.dependency-management")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
dependencies {
implementation("com.google.cloud:spring-cloud-gcp-dependencies:3.4.3")
implementation("com.google.cloud.sql:mysql-socket-factory:1.9.0")
implementation("com.google.cloud:google-cloud-storage:2.17.2")
implementation("org.springframework.cloud:spring-cloud-gcp-starter-sql-mysql:1.2.8.RELEASE")
implementation("org.springframework.boot:spring-boot-starter-actuator:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-security:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-data-jdbc:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-data-rest:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-data-jpa:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-web:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-validation:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-batch:2.7.8")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3")
implementation("org.springframework.boot:spring-boot-starter-validation:2.7.8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
runtimeOnly("com.h2database:h2:2.1.214")
implementation("org.hibernate.validator:hibernate-validator:7.0.5.Final")
runtimeOnly("mysql:mysql-connector-java:8.0.30")
implementation("com.google.zxing:core:3.5.0")
implementation("com.google.zxing:javase:3.5.0")
implementation("org.apache.commons:commons-csv:1.9.0")
implementation(project(":authentication"))
implementation(project(":commerce"))
testImplementation("org.springframework.boot:spring-boot-starter-test:3.0.2")
testImplementation(kotlin("test"))
}
Module 1
import org.springframework.boot.gradle.tasks.bundling.BootJar
tasks.getByName<BootJar>("bootJar") {
enabled = false
}
tasks.getByName<Jar>("jar") {
enabled = true
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-rest:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-security:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-data-jpa:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-data-jdbc:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-web:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-mail:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf:2.7.8")
implementation("com.nimbusds:nimbus-jose-jwt:9.23")
implementation("com.google.api-client:google-api-client-java6:2.0.0")
}
Module 2
import org.springframework.boot.gradle.tasks.bundling.BootJar
tasks.getByName<BootJar>("bootJar") {
enabled = false
}
tasks.getByName<Jar>("jar") {
enabled = true
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-rest:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-web:2.7.8")
implementation("org.springframework.boot:spring-boot-starter-data-jpa:2.7.8")
implementation("com.stripe:stripe-java:21.2.0")
implementation("org.springframework.boot:spring-boot-starter-security:2.7.8")
}
Edit 2:
Looking at the debugger, I've found that the original object has all the properties, seems like when I use userManager for example in an endpoint, it is accessing the proxy's property or something instead of the original one.

Related

Spring Dependency Management plugin for Spring Shell and Gradle multi-module project

I have a multi-module Gradle project which is structured like so:
root
|
|_____main
|
|_____other
This is how the build.gradle.ktss files are structured:
Root:
import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.8.0" apply false
kotlin("plugin.spring") version "1.8.0" apply false
kotlin("plugin.lombok") version "1.8.0" apply false
id("org.springframework.boot") version "2.7.2" apply false
id("io.spring.dependency-management") version "1.0.12.RELEASE" apply false
}
subprojects {
apply {
plugin("org.jetbrains.kotlin.jvm")
plugin("org.jetbrains.kotlin.plugin.spring")
plugin("org.jetbrains.kotlin.plugin.lombok")
plugin("org.springframework.boot")
plugin("io.spring.dependency-management")
}
configurations {
configurations["compileOnly"].extendsFrom(configurations["annotationProcessor"])
all {
exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
}
}
repositories {
mavenCentral()
}
val implementation by configurations
val testImplementation by configurations
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("org.springframework.boot:spring-boot-starter")
//other dependencies...
}
configure<DependencyManagementExtension> {
imports {
mavenBom("org.springframework.shell:spring-shell-dependencies:2.1.0")
}
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict", "-Xjvm-default=all")
jvmTarget = "17"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
}
Main:
import org.springframework.boot.gradle.tasks.bundling.BootJar
plugins {
`java-test-fixtures`
application
}
group = "my.group"
version = "0.2.0"
java.sourceCompatibility = JavaVersion.VERSION_17
application {
mainClass.set("my.group.MainKt")
}
tasks.withType<BootJar> {
manifest {
attributes["Main-Class"] = "org.springframework.boot.loader.PropertiesLauncher"
}
}
task<JavaExec>("runBootJar") {
val bootJar: BootJar by tasks
classpath = files(bootJar)
debug = true
}
springBoot {
buildInfo()
}
extra["springShellVersion"] = "2.1.0"
dependencies {
implementation("org.springframework.boot:spring-boot-loader")
api("org.springframework.boot:spring-boot-starter-web")
api("org.springframework.boot:spring-boot-starter-batch")
api("org.springframework.boot:spring-boot-starter-data-mongodb")
api("org.springframework.boot:spring-boot-starter-data-jpa")
api("org.springframework.boot:spring-boot-starter-integration")
api("org.springframework.boot:spring-boot-starter-thymeleaf")
api("org.springframework.boot:spring-boot-starter-log4j2")
api("org.springframework.integration:spring-integration-mongodb")
api("org.springframework.boot:spring-boot-starter-mail")
api("org.springframework.shell:spring-shell-starter")
//other dependencies...
}
Other:
plugins {
`java-library`
}
group = "my.group"
version = "0.2.0"
java.sourceCompatibility = JavaVersion.VERSION_17
dependencies {
compileOnly(project(":main"))
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
//other dependencies...
}
As you can see, Main has a dependency towards org.springframework.shell:spring-shell-starter, which in turns makes this piece inside the Root build.gradle.kts mandatory:
configure<DependencyManagementExtension> {
imports {
mavenBom("org.springframework.shell:spring-shell-dependencies:2.1.0")
}
}
If I try to move this part inside the Main script, the following error pops up when I try to compile Other:
Execution failed for task ':other:compileKotlin'.
> Could not resolve all files for configuration ':other:compileClasspath'.
> Could not find org.springframework.shell:spring-shell-starter:.
Required by:
project :other> project :main
Also, if I run Gradle with the stacktrace enabled, there is also this error:
2: Task failed with an exception.
-----------
* What went wrong:
java.lang.StackOverflowError (no error message)
This made me think there could be some kind of cyclic dependency, but I couldn't find any.
I'd like to move the mavenBom part inside Main because Spring Shell is only used there, and not in every submodule, but in the end I cannot get it working.
What am I missing?

Generated RelativePathProvider doesn't compile when use springfox and org.openapi.generator in SpringBoot web application

I'm trying to implement a simple spring boot web mvc application, but requirements are:
Generate code from api.yaml (openapi 3.0)
Generate swagger's code ( I guess it's just a couple of annotations but nevertheless)
But generated code doesn't compile due to generated:
import springfox.documentation.spring.web.paths.RelativePathProvider;
in org/openapitools/configuration/OpenAPIDocumentationConfig.java
my searching results summarized:
it's due to old springfox version, migrate to 3.0.0. The RelativePathProvider was replaced by DefaultPathProvider
but I'd already have it originally. And it'seems the generator doesn't know it need to generate DefaultPathProvider instead of old RelativePathProvider
My build.gradle.kts is:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.5.6"
id("org.openapi.generator").version("5.3.0")
id("io.spring.dependency-management") version "1.0.11.RELEASE"
kotlin("jvm") version "1.5.31"
kotlin("plugin.spring") version "1.5.31"
kotlin("plugin.jpa") version "1.5.31"
}
group = "com.hometask"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("javax.validation:validation-api:2.0.1.Final")
implementation("org.flywaydb:flyway-core")
api("io.springfox:springfox-swagger2:3.0.0")
api("io.springfox:springfox-swagger-ui:3.0.0")
api("org.openapitools:jackson-databind-nullable:0.2.1")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
compileOnly("org.projectlombok:lombok")
runtimeOnly("com.h2database:h2")
annotationProcessor("org.projectlombok:lombok")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
val spec = "$rootDir/src/main/resources/openapi/api.yml"
val generatedSourcesDir = "$buildDir/generated/openapi"
openApiGenerate {
generatorName.set("spring")
inputSpec.set(spec)
outputDir.set(generatedSourcesDir)
apiPackage.set("org.openapi.example.api")
invokerPackage.set("org.openapi.example.invoker")
modelPackage.set("org.openapi.example.model")
configOptions.set(mapOf(
"dateLibrary" to "java8"
))
}
sourceSets {
getByName("main") {
java {
srcDir("$generatedSourcesDir/src/main/java")
}
}
}
tasks {
val openApiGenerate by getting
val compileJava by getting {
dependsOn(openApiGenerate)
}
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}

WebFlux and Kotlin use ReactiveCrudRepository in multimodule application

I have an example SpringBoot app in Kotlin and WebFlux. I divided whole application into modules (as I'm used to from asp.net).
Modules:
core (models, DTO, helpers, etc...) referenced everywhere
data (repositories, tables...) referenced only in business
business (services, handlers...) referenced in api
api actual SpringBoot application
My problem now is how to properly work with ReactiveCrudRepository<> and repositories in general. I have config class in data module to enable R2dbcRepositories.
#Configuration
#EnableR2dbcRepositories("me.janam.data")
open class RepositoriesConfiguration {
}
Now if I create table and repository
interface IPersonRepository: ReactiveCrudRepository<PersonTable, Long> {
#Query("SELECT * FROM person.person limit 1")
fun getOne(): Mono<PersonTable>
}
and try to use it in business module I'm getting an error
Cannot access 'org.springframework.data.repository.reactive.ReactiveCrudRepository' which is a supertype of 'me.janam.data.features.person.repositories.IPersonRepository'. Check your module classpath for missing or conflicting dependencies
Of course if I add
implementation("org.springframework.data:spring-data-commons:2.4.6")
into my business module everything works fine. But somehow this feels strange to me. Is this the right way how to do this?
Also not part of my main question but here is complete config and I like to hear some opinion on it as i'm mainly asp.net dev. Thx.
root - settings.gradle.kts:
rootProject.name = "springboot-example"
include(":api")
include(":business")
include(":data")
include(":core")
root - gradle.properties:
kotlin.code.style=official
kotlin_version=1.4.31
kotlinx_coroutines_reactor_version=1.4.3
r2dbc_postgresql_version=0.8.7.RELEASE
postgresql_version=42.2.19
spring_context_version=5.3.5
root - build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.4.31"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
}
subprojects {
apply(plugin = "io.spring.dependency-management" )
dependencyManagement {
}
}
group = "me.janam"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
//implementation("org.springframework:spring-context:5.3.5")
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "13"
}
core - build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm")
}
group = "me.janam"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "13"
}
data - build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val kotlinx_coroutines_reactor_version: String by project
val r2dbc_postgresql_version: String by project
val postgresql_version: String by project
val spring_context_version: String by project
plugins {
kotlin("jvm")
}
group = "me.janam"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation(project(":core"))
implementation("org.springframework:spring-context:$spring_context_version")
implementation("org.springframework.boot:spring-boot-starter-data-r2dbc:2.4.4")
runtimeOnly("io.r2dbc:r2dbc-postgresql:$r2dbc_postgresql_version")
runtimeOnly("org.postgresql:postgresql:$postgresql_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinx_coroutines_reactor_version")
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "13"
}
business - build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val kotlinx_coroutines_reactor_version: String by project
val spring_context_version: String by project
plugins {
kotlin("jvm")
}
group = "me.janam"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation(project(":core"))
implementation(project(":data"))
implementation("org.springframework:spring-context:$spring_context_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinx_coroutines_reactor_version")
implementation("org.springframework.data:spring-data-commons:2.4.6") //TODO
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "13"
}
api - build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.4.4"
// Přesunuto do rootu
id("io.spring.dependency-management")
kotlin("jvm")
kotlin("plugin.spring") version "1.4.31"
}
group = "me.janam"
version = "1.0-SNAPSHOT"
//java.sourceCompatibility = JavaVersion.VERSION_13
repositories {
mavenCentral()
}
dependencies {
implementation(project(":core"))
implementation(project(":business"))
//implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
implementation("org.springframework.boot:spring-boot-starter-rsocket")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
//runtimeOnly("io.r2dbc:r2dbc-postgresql")
//runtimeOnly("org.postgresql:postgresql")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "13"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
Adding the same set of dependencies to each subproject may feel odd, but it's totally fine to do. In order to use a given dependency in a given subproject, you'll have to specify it as a dependency for that subproject.
There are, however, neater ways to accomplish this than actually copy-pasting the import statement to each build file. I would suggest specifying a subprojects section in your root build.gradle.kts and putting shared & common dependencies there:
subprojects {
dependencies {
// Put items here that are used in all/most subprojects:
implementation("org.springframework:spring-context:$spring_context_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinx_coroutines_reactor_version")
// You can put this import here or just keep it in the build files
// for subprojects where it will actually get used
implementation("org.springframework.data:spring-data-commons:2.4.6")
testImplementation(kotlin("test-junit5"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
}
You'll still need to specify in each sub-build file what other subprojects each depends on with implementation(project(":core")) type statements, but the above dependencies block takes care of making the specified libraries accessible in all subprojects.

SpringBoot gradle multimodule project Unresolved reference error

I'm trying to create a multimodule springboot application on gradle, but I get an Unresolved reference error message during build. Gradle config for individual modules is below.
Unresolved reference error on import org.example.finalmultimodule.data.repositories.IPersonRepository during build:
Error:
Directory tree:
BuildTools > Gradle:
Main build.gradle:
plugins {
id("org.springframework.boot") version "2.3.3.RELEASE"
id("io.spring.dependency-management") version "1.0.10.RELEASE"
kotlin("plugin.spring") version "1.4.10"
kotlin("jvm") version "1.4.10"
}
group = "org.example"
version = "1.0-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
// Projekty
project(":data") {
apply(plugin = "org.springframework.boot")
apply(plugin = "io.spring.dependency-management")
}
project(":business") {
apply(plugin = "org.springframework.boot")
apply(plugin = "io.spring.dependency-management")
}
project(":api") {
apply(plugin = "org.springframework.boot")
apply(plugin = "io.spring.dependency-management")
}
dependencies {
// Moduly
implementation(project(":core"))
implementation(project(":data"))
implementation(project(":business"))
implementation(project(":api"))
implementation(kotlin("stdlib"))
}
allprojects {
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
}
Core build.gradle:
plugins {
kotlin("jvm")
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
// Anotace pro #JsonProperty
implementation("com.fasterxml.jackson.core:jackson-annotations:2.11.2")
implementation(kotlin("stdlib"))
}
Data build.gradle:
plugins {
kotlin("jvm")
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
// Moduly
implementation(project(":core"))
// Anotace #Component etc...
implementation("org.springframework:spring-context")
// Corutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
// Databaze
implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
implementation("io.r2dbc:r2dbc-mssql")
implementation(kotlin("stdlib"))
}
Business build.gradle:
plugins {
kotlin("jvm")
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation(project(":core"))
implementation(project(":data"))
// Kediatr variace na Mediatr
implementation("com.trendyol:kediatr-spring-starter:1.0.14")
implementation(kotlin("stdlib"))
}
Api (springboot) build.gradle:
plugins {
kotlin("jvm")
kotlin("plugin.spring")
}
group = "org.example"
version = "0.0.1-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
// Moduly
implementation(project(":core"))
implementation(project(":business"))
// Kediatr variace na Mediatr
implementation("com.trendyol:kediatr-spring-starter:1.0.14")
implementation("org.springframework.boot:spring-boot-starter-rsocket")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
}
testImplementation("io.projectreactor:reactor-test")
}
I had a very similar situation where my classes from other modules would not be resolved even though everything looked fine in IntelliJ.
I managed to solve it by explicitly adding
#ComponentScan(basePackages = ["my.package"])
to my spring boot application.
Also, set library projects up like this:
tasks.findByName("bootJar")?.apply {
enabled = false
}
tasks.findByName("jar")?.apply {
enabled = true
}

Import of external class in Kotlin Gradle Script not found

In my build.gradle.kts, I want to write a function that uses an external class: StrSubstitutor from Apach Commons Text. However, the import is not found, although I can see the library when I run ./gradlew dependencies.
The build.gradle.kts file is as follows:
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.apache.commons.text.StringSubstitutor // Import not found
plugins {
val kotlinVersion = "1.3.61"
kotlin("jvm") version "$kotlinVersion"
kotlin("kapt") version "$kotlinVersion"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
dependencies {
implementation("org.apache.commons:commons-text:1.8")
// SourceSets
sourceSets.main {
withConvention(KotlinSourceSet::class) {
kotlin.srcDirs("src/main/kotlin")
}
}
sourceSets.test {
withConvention(KotlinSourceSet::class) {
kotlin.srcDirs("src/main/kotlin")
}
}
}
tasks.withType<Test> {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
systemProperty("spring.profiles.active", "test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
// Function that uses the import
fun getProperty(properties: Properties, propertyKey: String): String {
// Use the import "StrSubstitutor"
return ""
}
Is this possible with Kotlin, and if so: how?
Yes, it is possible. The reason it does not work as written is because you put the dependency on the Apache Commons Text into implementation configuration of the project, not into the classpath of the build script itself. So, you basically need to introduce a buildscript block to your build.gradle.kts file. Below is an example1:
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.apache.commons.text.StringSubstitutor
// TL DR: Add this block to your build script to make the import above work
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.apache.commons:commons-text:1.8")
}
}
tasks.register("hello") {
doLast {
println(StringSubstitutor.replaceSystemProperties(
"You are running with Java \${java.version} on OS \${os.name}."))
}
}
plugins {
val kotlinVersion = "1.3.61"
kotlin("jvm") version "$kotlinVersion"
kotlin("kapt") version "$kotlinVersion"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
dependencies {
// You probably do not need this for your project, so I commented it out
// implementation("org.apache.commons:commons-text:1.8")
// SourceSets
sourceSets.main {
withConvention(KotlinSourceSet::class) {
kotlin.srcDirs("src/main/kotlin")
}
}
sourceSets.test {
withConvention(KotlinSourceSet::class) {
kotlin.srcDirs("src/main/kotlin")
}
}
}
tasks.withType<Test> {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
systemProperty("spring.profiles.active", "test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
Run this script with ./gradlew -q hello to check whether it works or not.
1 New task hello exists there just to demonstrate that the import works, it is not needed in the final build script that you would use in your project.

Resources