Search code examples
kotlinmicronaut

Page not found message using micronaut, Gradle and Kotlin


I just started using Micronaut, but I can't get a simple endpoint to work. I get this response for http://localhost:8901/game_compositions/

{
"message": "Page Not Found",
"_links": {
    "self": {
        "href": "/game_compositions/",
        "templated": false
    }
}
}

I have seen a few other questions here about the same response but none of them helped me. I have annotation processor activated for my build and I do not return null.

I assume I have some simple stupid mistake, but I can't find it. According to the sample projects I seem to have all I need.

This is my project:

Controller:

import io.micronaut.http.MediaType
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces

@Controller("/game_compositions")
class CompositionsController {

    @Produces(MediaType.APPLICATION_JSON)
    @Get(uri = "/")
    fun getCompositions(): Iterable<String> {
        return listOf("something")
    }
}

Build.gradle (mostly autogenerated from the https://micronaut.io/launch/ site, so there might be some unnecessary stuff there for a simple service. Feel free to point it out)

plugins {
    id("io.micronaut.application") version "1.2.0"
    kotlin("jvm") version "1.4.10"
    kotlin("kapt") version "1.4.10"
    kotlin("plugin.allopen") version "1.4.10"
}

version = "0.1"
group = "com.example.backend"

val kotlinVersion=project.properties.get("kotlinVersion")
repositories {
    mavenCentral()
    jcenter()
}

micronaut {
    runtime("netty")
    testRuntime("junit5")
    processing {
        incremental(true)
        annotations("com.example.backend.*")
    }
}

dependencies {
    implementation("io.micronaut:micronaut-validation")
    implementation("io.micronaut.kotlin:micronaut-kotlin-runtime")
    implementation("io.micronaut:micronaut-runtime")
    implementation("io.micronaut.sql:micronaut-jdbc-hikari")
    implementation("io.micronaut.sql:micronaut-hibernate-jpa")

    runtimeOnly("org.mariadb.jdbc:mariadb-java-client")

    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
    implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")

    runtimeOnly("ch.qos.logback:logback-classic")

    runtimeOnly("com.fasterxml.jackson.module:jackson-module-kotlin")
}


application {
    mainClass.set("com.example.backend.ApplicationKt")
}

java {
    sourceCompatibility = JavaVersion.toVersion("14")
}

tasks {
    compileKotlin {
        kotlinOptions {
            jvmTarget = "14"
        }
    }
    compileTestKotlin {
        kotlinOptions {
            jvmTarget = "14"
        }
    }
}

Application.yml (the database connection is so far unused untested)

micronaut: application: name: Backend server: port: 8901

datasources: default: url: jdbc:mysql://localhost:3306/db username: root password: root driver-class-name: org.mariadb.jdbc.Driver

jpa: default: properties: hibernate: hbm2ddl: auto: none show_sql: true


Solution

  • Thanks to Jeff Scott Brown in the comments I have been able to determine that the order of the plugins is the problem. I was not aware that the order mattered in gradle. Apparently Micronaut requires the kapt plugin to be added first. Anyone with more insight in to this is welcome to post a better answer, for me it worked to change the start of my gradle file to this:

    plugins {
        kotlin("jvm") version "1.4.10"
        kotlin("kapt") version "1.4.10"
        id("io.micronaut.application") version "1.2.0"
        kotlin("plugin.allopen") version "1.4.10"
    }
    

    Edit: An important note if anyone attempts to use my gradle file. It turns out kapt does not support java 14 and that caused some very hard to track down trouble for me. This is my current working gradle file:

    plugins {
        kotlin("jvm") version "1.4.10"
        kotlin("kapt") version "1.4.10"
        kotlin("plugin.allopen") version "1.4.10"
        kotlin("plugin.jpa") version "1.4.10"
        id("io.micronaut.application") version "1.2.0"
    }
    
    version = "0.1"
    group = "com.example.backend"
    
    val kotlinVersion: String by project
    
    repositories {
        mavenCentral()
        jcenter()
    }
    
    micronaut {
        runtime("netty")
        testRuntime("junit5")
        processing {
            incremental(true)
            annotations("com.example.backend.*")
        }
    }
    
    dependencies {
        annotationProcessor("io.micronaut.data:micronaut-data-processor")
        implementation("io.micronaut:micronaut-validation")
        implementation("io.micronaut.kotlin:micronaut-kotlin-runtime")
        implementation("io.micronaut:micronaut-runtime")
        implementation("io.micronaut.sql:micronaut-jdbc-hikari")
        implementation("io.micronaut.sql:micronaut-hibernate-jpa")
        implementation("io.micronaut.data:micronaut-data-hibernate-jpa")
    
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
        implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
    
        runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
    
        runtimeOnly("ch.qos.logback:logback-classic")
    
        runtimeOnly("com.fasterxml.jackson.module:jackson-module-kotlin")
    }
    
    
    application {
        mainClass.set("com.example.backend.ApplicationKt")
    }
    
    java {
        sourceCompatibility = JavaVersion.toVersion("11")
    }
    
    tasks {
        compileKotlin {
            kotlinOptions {
                jvmTarget = "11"
            }
        }
        compileTestKotlin {
            kotlinOptions {
                jvmTarget = "11"
            }
        }
    }