When I try to send object in body of POST method to micronaut application I get: model: Cannot validate com.example.Model. No bean introspection present. Please add @Introspected to the class and ensure Micronaut annotation processing is enabled.
The structure of the project consist of two modules main and model. The main module have dependency to the model module.
The main module contains only of the DefaultTestController class:
import io.micronaut.http.annotation.Body
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Post
import io.micronaut.validation.Validated
import javax.validation.Valid
@Controller("/test")
@Validated
class DefaultTestController : TestController {
@Post
override fun create(@Body @Valid model: Model) {
println("Model: $model")
}
}
And its build.gradle.kts file looks like this:
plugins {
id("org.jetbrains.kotlin.jvm") version "1.6.0"
id("org.jetbrains.kotlin.kapt") version "1.6.0"
id("org.jetbrains.kotlin.plugin.allopen") version "1.6.0"
id("com.github.johnrengelman.shadow") version "7.1.0"
id("io.micronaut.application") version "3.0.2"
}
version = "0.1"
group = "com.example"
val kotlinVersion = project.properties.get("kotlinVersion")
repositories {
mavenCentral()
}
micronaut {
runtime("netty")
testRuntime("junit5")
processing {
incremental(true)
annotations("com.example.*")
}
}
dependencies {
kapt("io.micronaut:micronaut-http-validation:3.2.2")
implementation("io.micronaut:micronaut-http-client:3.2.2")
implementation("io.micronaut:micronaut-runtime:3.2.2")
implementation("io.micronaut.kotlin:micronaut-kotlin-runtime:3.0.0")
implementation("jakarta.annotation:jakarta.annotation-api:2.0.0")
implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
runtimeOnly("ch.qos.logback:logback-classic:1.2.7")
implementation("io.micronaut:micronaut-validation:3.2.2")
runtimeOnly("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.0")
implementation("io.micronaut:micronaut-inject:3.2.2")
annotationProcessor("io.micronaut:micronaut-inject-java:3.2.2")
implementation(project(":model"))
}
application {
mainClass.set("com.example.ApplicationKt")
}
java {
sourceCompatibility = JavaVersion.toVersion("11")
}
tasks {
compileKotlin {
kotlinOptions {
jvmTarget = "11"
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "11"
}
}
}
The model module contains:
import io.micronaut.core.annotation.Introspected
import javax.validation.Valid
@Introspected
data class Model(
@field:Valid
val subModel: SubModel
)
import io.micronaut.core.annotation.Introspected
import javax.validation.constraints.Email
@Introspected
data class SubModel(
@field:Email
val email: String
)
And its build.gradle.kts file looks like this:
plugins {
kotlin("jvm")
}
group = "com.example"
version = "0.1"
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib"))
implementation("io.micronaut:micronaut-validation:3.2.2")
annotationProcessor("io.micronaut:micronaut-validation:3.2.2")
implementation("io.micronaut:micronaut-http-validation:3.2.2")
annotationProcessor("io.micronaut:micronaut-http-validation:3.2.2")
implementation("io.micronaut:micronaut-inject:3.2.2")
annotationProcessor("io.micronaut:micronaut-inject-java:3.2.2")
}
The gradle.properties file:
micronautVersion=3.2.2
kotlinVersion=1.6.0
org.gradle.java.installations.auto-download=false
org.gradle.java.installations.auto-detect=false
org.gradle.java.installations.fromEnv=JAVA_HOME
When I move the Model and SubModel to the main module everything works as expected.
When I remove @Validated
and @Valid
annotations from DefaultTestController then it is also working, but the email is not validated.
I tried many different possibilities of adding and removing various dependencies (e.g. described here: Validating the POJO record with Micronaut not working and Cannot validate view.model.product.ProductSearchCriteria. No bean introspection present. Please add @Introspected to the class) but nothing worked as expected. Can someone take a look and help me solve this problem?
EDIT:
Here is the repository with code example: github.com/stefanik36/Micronaut-Introspection-Problem. It contains src/test/kotlin/com/example/DefaultTestControllerTest.kt
test which will pass when the Model
and SubModel
classes will be moved to the main module.
This can be solved by including of io.micronaut.library gradle plugin in model gradle module and then only io.micronaut:micronaut-validation
implementation dependency is required.
After these changes content of the model/build.gradle.kts file will look like:
plugins {
kotlin("jvm")
id("org.jetbrains.kotlin.kapt")
id("io.micronaut.library")
}
group = "com.example"
version = "0.1"
repositories {
mavenCentral()
}
dependencies {
implementation("io.micronaut:micronaut-validation")
}
After this change validation defined in classes from separate gradle module and annotated by @Introspected
will work.