Closed dfernandezm closed 1 week ago
Can't reproduce this exception with your example. But I see that you have bug in your schema: need to set any path. I tried to generate code by schema with path /
, but I can't catch this exception:
Generated server code and openapi file by this generated code:
@dfernandezm ping
Ok,If you still have a problem, update the example and write about it - we will reopen the ticket
Hi, sorry for late reply @altro3, I've been away.
Thanks for trying to recreate this, all it's a bit confusing but I still get the error my side. It can be environmental, I'll try to add more detail.
I amended the spec to have a minimal failing one and validated it with Swagger editor too.
This is the build.gradle
relevant chunk:
plugins {
id 'io.micronaut.application' version '4.4.0'
id 'com.google.cloud.tools.jib' version '3.4.3'
id 'org.openapi.generator' version '7.7.0'
id 'io.micronaut.openapi' version '4.4.2'
}
micronaut {
version "4.5.0"
importMicronautPlatform = true
processing {
// Sets whether incremental annotation processing is enabled
incremental true
}
// Filed issue https://github.com/micronaut-projects/micronaut-openapi/issues/1700
openapi {
server(file("$rootDir/api/test-issue.yml")) {
apiPackageName = "com.api.openapi.generated.api"
modelPackageName = "com.api.openapi.generated.model"
useReactive = false
useAuth = true
}
}
}
dependencies {
annotationProcessor("io.micronaut:micronaut-http-validation")
annotationProcessor("io.micronaut.security:micronaut-security-annotations")
annotationProcessor("io.micronaut.serde:micronaut-serde-processor")
annotationProcessor("io.micronaut.validation:micronaut-validation-processor")
implementation("io.micronaut.validation:micronaut-validation")
annotationProcessor("io.micronaut:micronaut-inject-java")
annotationProcessor("io.micronaut.openapi:micronaut-openapi:6.11.1")
compileOnly("io.micronaut.openapi:micronaut-openapi-annotations:6.11.1")
implementation("io.micronaut.openapi:micronaut-openapi-annotations:6.11.1")
implementation("io.micronaut.openapi:micronaut-openapi-common:6.11.1")
implementation("io.micronaut.serde:micronaut-serde-jackson")
implementation("org.openapitools:jackson-databind-nullable:0.2.6")
implementation("io.micronaut:micronaut-http-client")
implementation("io.micronaut:micronaut-http-server")
implementation("io.micronaut:micronaut-jackson-databind")
annotationProcessor("io.micronaut.validation:micronaut-validation-processor")
implementation("io.micronaut.validation:micronaut-validation")
implementation("jakarta.annotation:jakarta.annotation-api")
implementation("io.micronaut.security:micronaut-security")
implementation("io.micronaut.security:micronaut-security-jwt")
}
The spec I'm using:
openapi: 3.0.1
info:
title: Test
description: |
Something
paths:
/predictions/models/{modelKey}:
post:
tags:
- Predictions
summary: Create a prediction
description: |
Creates a new prediction using the dataset and model specified
for the blind CSV
operationId: createPrediction
parameters:
- name: modelKey
in: path
required: true
schema:
type: string
format: uuid
requestBody:
content:
text/csv:
schema:
type: string
format: binary
multipart/form-data:
schema:
type: string
format: binary
required: true
responses:
"200":
description: Prediction created successfully
content:
application/json:
schema:
$ref: "#/components/schemas/PredictionCreationOutput"
examples:
Successful prediction creation:
summary: Successful prediction creation
value:
predictionKey: 3a1a9a83-d549-4f25-b7ed-8174e0c955de
status: "RUNNING"
predictionCreationProgressUrl: 2b0a9a83-d549-4f25-b7ed-8174e0c955cd
"400":
description: Invalid prediction submission
"500":
description: Internal server error
components:
schemas:
DatasetCreationOutput:
required:
- datasetCreationProgressUrl
- datasetKey
- status
type: object
properties:
datasetKey:
pattern: "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
type: string
format: uuid
status:
$ref: "#/components/schemas/DatasetCreationStatus"
datasetCreationProgressUrl:
type: string
DatasetCreationRequest:
required:
- datasetName
type: object
properties:
datasetName:
maximum: 30
minimum: 3
type: string
description: The unique dataset name
description:
maximum: 150
minimum: 3
type: string
description: The dataset description in plain text
nullable: true
PredictionCreationOutput:
required:
- predictionCreationProgressUrl
- predictionKey
- status
type: object
properties:
predictionKey:
pattern: "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
type: string
format: uuid
status:
$ref: "#/components/schemas/DatasetCreationStatus"
predictionCreationProgressUrl:
type: string
DatasetCreationStatus:
type: string
description: |+
Status of dataset creation:
* `PENDING`
* `PROCESSING`
* `COMPLETED`
* `FAILED`
enum:
- PENDING
- PROCESSING
- COMPLETED
- FAILED
Codegen seems to work, but compileJava
fails badly:
> Task :bai-api:generateServerOpenApiApis
Missing required field info version. Default appVersion set to 1.0.0
Missing required field info version. Default version set to 1.0.0
################################################################################
# Thanks for using OpenAPI Generator. #
# Please consider donation to help us maintain this project 🙏 #
# https://opencollective.com/openapi_generator/donate #
################################################################################
> Task :bai-api:generateServerOpenApiModels
Missing required field info version. Default appVersion set to 1.0.0
Missing required field info version. Default version set to 1.0.0
Validation 'minimum' has no effect on schema 'string'. Ignoring!
Validation 'maximum' has no effect on schema 'string'. Ignoring!
Validation 'minimum' has no effect on schema 'string'. Ignoring!
Validation 'maximum' has no effect on schema 'string'. Ignoring!
################################################################################
# Thanks for using OpenAPI Generator. #
# Please consider donation to help us maintain this project 🙏 #
# https://opencollective.com/openapi_generator/donate #
################################################################################
> Task :bai-api:compileJava FAILED
Note: Generating OpenAPI Documentation
warning: Error:
Cannot invoke "io.swagger.v3.oas.models.responses.ApiResponse.getContent()" because "apiResponse" is null
java.lang.NullPointerException: Cannot invoke "io.swagger.v3.oas.models.responses.ApiResponse.getContent()" because "apiResponse" is null
at io.micronaut.openapi.visitor.OpenApiNormalizeUtils.normalizeOperation(OpenApiNormalizeUtils.java:136)
at io.micronaut.openapi.visitor.OpenApiNormalizeUtils.normalizeOpenApi(OpenApiNormalizeUtils.java:70)
at io.micronaut.openapi.visitor.OpenApiApplicationVisitor.postProcessOpenApi(OpenApiApplicationVisitor.java:698)
at io.micronaut.openapi.visitor.OpenApiApplicationVisitor.finish(OpenApiApplicationVisitor.java:472)
at io.micronaut.annotation.processing.TypeElementVisitorProcessor.process(TypeElementVisitorProcessor.java:281)
at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.process(DelegatingProcessor.java:62)
at org.gradle.api.internal.tasks.compile.processing.DynamicProcessor.process(DynamicProcessor.java:52)
at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.process(DelegatingProcessor.java:62)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.access$401(TimeTrackingProcessor.java:37)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$5.create(TimeTrackingProcessor.java:99)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$5.create(TimeTrackingProcessor.java:96)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.track(TimeTrackingProcessor.java:117)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.process(TimeTrackingProcessor.java:96)
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:1021)
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:937)
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1265)
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1380)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1271)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:948)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
at org.gradle.internal.compiler.java.IncrementalCompileTask.call(IncrementalCompileTask.java:92)
at org.gradle.api.internal.tasks.compile.AnnotationProcessingCompileTask.call(AnnotationProcessingCompileTask.java:94)
at org.gradle.api.internal.tasks.compile.ResourceCleaningCompilationTask.call(ResourceCleaningCompilationTask.java:57)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:55)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:39)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:98)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:52)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:38)
at org.gradle.api.internal.tasks.compile.AnnotationProcessorDiscoveringCompiler.execute(AnnotationProcessorDiscoveringCompiler.java:51)
at org.gradle.api.internal.tasks.compile.AnnotationProcessorDiscoveringCompiler.execute(AnnotationProcessorDiscoveringCompiler.java:37)
at org.gradle.api.internal.tasks.compile.ModuleApplicationNameWritingCompiler.execute(ModuleApplicationNameWritingCompiler.java:46)
at org.gradle.api.internal.tasks.compile.ModuleApplicationNameWritingCompiler.execute(ModuleApplicationNameWritingCompiler.java:36)
at org.gradle.jvm.toolchain.internal.DefaultToolchainJavaCompiler.execute(DefaultToolchainJavaCompiler.java:57)
at org.gradle.api.tasks.compile.JavaCompile.lambda$createToolchainCompiler$3(JavaCompile.java:202)
at org.gradle.api.internal.tasks.compile.CleaningJavaCompiler.execute(CleaningJavaCompiler.java:53)
at org.gradle.api.internal.tasks.compile.incremental.IncrementalCompilerFactory.lambda$createRebuildAllCompiler$0(IncrementalCompilerFactory.java:52)
Codegen seems to work well (I can see apis and models) but compileJava task is throwing this obscure exception. Any guidance is appreciated
@dfernandezm Hm.. I still can't reproduce this bug.
Could you create a sample application to reproduce this bug?
The current information is not enough, because I can't reproduce your problem.
Also, try using the latest version of micronaut-openapi . Right now you are using a very old version 6.11.1
Unlikely, but possible: you're on a Mac and I'm on Windows, so it works for me and not for you.
It's extremely important that you create a complete, simple application to reproduce the problem.
Hi, thanks for the time again.
I've put 6.11.1 and still get the issue. The problem happens after code generation, and it's a gradle exception. It's likely I need to park this for a bit, but I'll attach a minimal application that reproduces the problem at the earliest. Thank you.
@dfernandezm Once again:
Please provide a working application with a reproduction of your bug - create a repository on github, add everything you need and tell me how to run it - I'll check everything.
Try updating the micronaut-openapi version to the latest. The latest version is 6.12.3
. Change 6.11.1
to 6.12.3
. 6.11.1
is a very old version.
I can't help you any other way.
HI @altro3 I finally found the issue. The clue was something about annotation processing in the exception. If there's classes in the project annotated with OpenAPI/Swagger annotations already, looks like there's a conflict of some sorts and the indicated Gradle exception happens.
Basically I had a controller like this:
@SuppressWarnings("unused")
@Controller("/predictions")
public interface PredictionOpenApiController extends OpenApiController {
static final String UUID_REGEX = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$";
@Tags({@Tag(name="Predictions")})
@Operation(
operationId = "createPrediction",
summary = "Create a prediction",
description = "Creates a new prediction using the dataset and model specified for the blind CSV")
@ApiResponses({
@ApiResponse(responseCode = "201", description = "Prediction created successfully",
content = @Content(schema = @Schema(implementation = PredictionCreationOutput.class),
examples = @ExampleObject(
name = "Successful prediction creation response",
summary = "Successful prediction creation response",
value = """
{
"predictionKey": "3a1a9a83-d549-4f25-b7ed-8174e0c955de",
"modelKey": "6a1a9a83-d549-4f25-b7ed-8174e0c955b",
"datasetKey": "2b0a9a83-d549-4f25-b7ed-8174e0c955cd"
"status": "PENDING",
"predictionProgressUrl": "http://server/api/predictions/3a1a9a83-d549-4f25-b7ed-8174e0c955de/progress"
}
"""
))),
@ApiResponse(responseCode = "400", description = "Invalid prediction submission"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
...
Before codegen , I was generating the spec from the code annotations (as it helps reason about outputs etc.). Now I use the base spec to do spec-first and iterate on it.
I don't think it's common at all gen code from spec and also have controllers annotated, so this issue won't happen to 99.9% of people. I can create a reproducer easily, but I wonder of its value given the extreme edge case. The error is very misleading though.
Thanks for the help!
Of course it is valuable because somehow you managed to add null
to the list of responses - I am very curious how it works and I want to fix this error. So please create a simple reproducer.
To manage expectations, it might take some time for me to generate this reproducer, as I need to progress with the project. But I will definitely do it so please leave the issue opened.
On a separate topic (can post question?) I find it hard to find docs on the basics of codegen from spec. I have a strong use case to generate server Micronaut from spec and I'm struggling to find many of the settings/features as seen at https://openapi-generator.tech/, I see that the Micronaut codegen moved to this project so I would've expected same features here? (for example additionalModelTypeAnnotations
from https://openapi-generator.tech/docs/generators/java-micronaut-server/)
That's right, the generator was moved here. So, regarding the settings that are supported, unfortunately, no one has written normal documentation for code generation.
But here you can find all the settings that can be set at the moment:
Thanks for the core info. Checking what's there, unfortunately I'll be stuck with OpenAPI generator core plugin with custom templates for a while then, as I need to heavily customise the models mainly (add extra annotations etc.) and don't see a way to override templates or use more configOptions that currently supported in the moved Micronaut Server generator (I'll keep an eye for updates though).
Regardless I'll provide the reproducer for the original issue as soon as I can, but with low priority as I need to make progress proving codegen / spec-first for this project.
If you see that there are some features that are supported in the main openapi generator, but they are not supported in the generator from micronaut - just create an issue.
I add features as requests come in.
@dfernandezm Please write in a separate issue a list of features that you need and that are not currently available - I will add them in the very near future.
@dfernandezm added support for additional annotations here: https://github.com/micronaut-projects/micronaut-openapi/pull/1771
@dfernandezm any news?
Expected Behavior
Using micronaut openapi 6.11.1
Code to generate from spec correctly
Actual Behaviour
NullPointerException when generating POST request
Steps To Reproduce
Environment Information
Example Application
No response
Version
4.5.0