Skip to content

java-micronaut-server And generateControllerAsAbstract=true Results in "class not found" Errors #21089

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
johnjvester opened this issue Apr 15, 2025 · 1 comment

Comments

@johnjvester
Copy link

java-micronaut-server And generateControllerAsAbstract=true Results in "class not found" Errors

I opted to not create a [BUG] issue, since the java-micronaut-server is still listed as a Beta version.

While working on a short article that leverages and OpenAPI specification to build services, I was able to successfully use Spring Boot and Quarkus. The final article of my series focused on Micronaut and I was excited to see that an OpenAPI generator exists for this framework.

By default, the 7.12.0 version of the generator ends up creating a DefaultController which is a class. I eventually discovered the generateControllerAsAbstract=true configuration option which did introduce the AbstractDefaultController however, with this change in place I started seeing "class not found" errors. What surprised me is that errors pointed to HttpStatusException and HttpStatus - both of which were in the class path and available in my local IntelliJ instance. If I were to switch back to generateControllerAsAbstract=false, the errors went away.

I also noticed that if I provided my own api, model and invoker packages, the AbstractDefaultController appeared to ignore these settings and created the class in the org.openapitools package.

Here is my build.gradle file:

plugins {
    id("io.micronaut.application") version "4.5.0"
    id("com.gradleup.shadow") version "8.3.6"
    id("io.micronaut.aot") version "4.5.0"
    id("org.openapi.generator") version '7.12.0'
}

openApiGenerate {
    generatorName = "java-micronaut-server"
    inputSpec = "$rootDir/src/main/resources/openapi.yaml"
    outputDir = "$buildDir/generated"
    //apiPackage = "quotes.micronaut.openapi.api"
    //modelPackage = "quotes.micronaut.openapi.model"
    //invokerPackage = "quotes.micronaut.openapi.invoker"
    configOptions = [
            dateLibrary: "java8",
            useJakartaEe: "true",
            useBeanValidation: "false",
            reactive: "false",
            generateControllerAsAbstract: "true",
    ]
}

version = "0.1"
group = "quotes.micronaut"

repositories {
    mavenCentral()
}

dependencies {
    annotationProcessor("io.micronaut:micronaut-http-validation")
    annotationProcessor("io.micronaut:micronaut-inject-java")
    annotationProcessor("io.micronaut.openapi:micronaut-openapi")
    annotationProcessor("io.micronaut.serde:micronaut-serde-processor")
    annotationProcessor("io.micronaut.validation:micronaut-validation-processor")
    annotationProcessor("org.projectlombok:lombok")

    implementation("io.micronaut:micronaut-http")
    implementation("io.micronaut.security:micronaut-security-annotations")
    implementation("io.micronaut.security:micronaut-security")
    implementation("io.micronaut.serde:micronaut-serde-jackson")
    implementation("io.micronaut.validation:micronaut-validation")

    compileOnly("io.micronaut:micronaut-http-server")
    compileOnly("io.micronaut.openapi:micronaut-openapi-annotations")
    compileOnly("org.projectlombok:lombok")

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

    testImplementation("io.micronaut:micronaut-http-client")
}


application {
    mainClass = "quotes.micronaut.Application"
}
java {
    sourceCompatibility = JavaVersion.toVersion("17")
    targetCompatibility = JavaVersion.toVersion("17")
}

sourceSets {
    main {
        java {
            srcDirs += "$buildDir/generated/src/main/java"
        }
    }
}

compileJava.dependsOn tasks.openApiGenerate
graalvmNative.toolchainDetection = false

micronaut {
    runtime("netty")
    testRuntime("junit5")
    processing {
        incremental(true)
        annotations("quotes.micronaut.*")
    }
    aot {
        // Please review carefully the optimizations enabled below
        // Check https://micronaut-projects.github.io/micronaut-aot/latest/guide/ for more details
        optimizeServiceLoading = false
        convertYamlToJava = false
        precomputeOperations = true
        cacheEnvironment = true
        optimizeClassLoading = true
        deduceEnvironment = true
        optimizeNetty = true
        replaceLogbackXml = true
    }
}

If interested, here's the OpenAPI Specification that I have been using for my articles:

openapi: 3.0.0
info:
  title: Motivational Quotes API
  description: An API that provides motivational quotes.
  version: 1.0.0
servers:
  - url: https://api.example.com
    description: Production server
paths:
  /quotes:
    get:
      summary: Get all motivational quotes
      operationId: getAllQuotes
      responses:
        '200':
          description: A list of motivational quotes
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Quote'
  /quotes/random:
    get:
      summary: Get a random motivational quote
      operationId: getRandomQuote
      responses:
        '200':
          description: A random motivational quote
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Quote'
  /quotes/{id}:
    get:
      summary: Get a motivational quote by ID
      operationId: getQuoteById
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: A motivational quote
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Quote'
        '404':
          description: Quote not found
components:
  schemas:
    Quote:
      type: object
      required:
        - id
        - quote
      properties:
        id:
          type: integer
        quote:
          type: string

I opted to go a different direction for the article, but I wanted to log this ticket, in case it provides value for someone else in the future.

Have a really great day!

@altro3
Copy link
Contributor

altro3 commented Apr 22, 2025

@johnjvester Hi! You use old deprecated generator. Please, use official micronaut-openapi-generator:

https://github.com/micronaut-projects/micronaut-openapi

Plugins for gradle and maven:

https://github.com/micronaut-projects/micronaut-gradle-plugin
https://github.com/micronaut-projects/micronaut-maven-plugin

Guide to use micronaut-openapi-generator:

https://guides.micronaut.io/latest/micronaut-openapi-generator-server

If you have some problems / suggestions, please create issues here:

https://github.com/micronaut-projects/micronaut-openapi/issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants