micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.01k stars 1.05k forks source link

Autogenerated (AnnotationProcessor) interface not being "indexed/processed" #6918

Open nbrugger-tgm opened 2 years ago

nbrugger-tgm commented 2 years ago

Expected Behavior

When you have an annotation processor that generates files like this:

import io.micronaut.http.annotation.Get;

public interface PingService {
    @Get("/ping")
    String ping();
}

and then manually add the implementation

import io.micronaut.http.annotation.Controller;

@Controller
public class PingResource implements PingService {
    @Override
    public String ping() {
        return "pong";
    }
}

The path /ping should be:

Actual Behaviour

The path /ping path is:

When changing the processor to generate this instead : (Adding the @Controller annotation to the interface)

package com.niton.localadmin.rest.controller;

import io.micronaut.http.annotation.*;

@Controller
public interface PingService {
    @Get("/ping")
    String ping();
}

the Open API generation works.

In Depth

This one is a pretty wild guess from my side and i have no clue if i am right but this is my guess without having had a deep dive into the sourcecode

This is what i think is causing the bug :

Again this is just an educated guess but since i did a little tiny bit of debugging i think it might still be valueable to you :)

Steps To Reproduce

  1. Generate micronaut app with features management and openapi (gradle)
  2. Add a gradle subproject called processor_of_death
  3. Add the aforementioned subproject to the micronaut app as annotationProcessor(project(":processor_of_death")) and also for the implementation config
  4. Add this annotation processor to the processor_of_death project (imports omitted)
    
    package com.example.processor;

@SupportedAnnotationTypes("io.micronaut.http.annotation.Controller") public class DtoInterfaceGenerator extends AbstractProcessor { @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { try (var writer = processingEnv.getFiler().createSourceFile("com.example.controller.PingService").openWriter()) { writer.append("package com.niton.localadmin.rest.controller;\n" + "\n" + "import io.micronaut.http.annotation.*;\n" + "\n" + "@Controller\n" + "public interface PingService {\n" + "\t@Get(\"/ping\")\n" + "\tString ping();\n" + "}\n"); } catch (IOException e) { e.printStackTrace(); } return false;//false to make the interface processable by others } }

5. Register the Processor using *SPI*
6. Add the interface implementation to the micronaut project
```java
@Controller
public class PingResource implements PingResource.PingService {
    @Override
    public String ping() {
        return "pong";
    }

}
  1. (optional) take the regarding steps to set up OpenApi processing from the micronaut doc here
  2. Run the micronaut project
  3. curl -X GET http://localhost:8080/ping will fail with 404 path not found ....
  4. Remove the annotation processor
  5. Add the interface to the micronautproject
  6. restart
  7. curl -X GET http://localhost:8080/ping will now work

Environment Information

Example Application

github.com/nbrugger-tgm

Version

3.3.1

nbrugger-tgm commented 2 years ago

Workaround

I found a workaround to get the expected result.

Split your project into 2 parts api and service or app where api is a micronaut lib that contains all the annotation processed code. And app is ... well, the app and contains the implementation of the api. This is the only reliable way to force annotation processor order, still it would be favorable to work out of the box

nbrugger-tgm commented 2 years ago

Related: https://github.com/micronaut-projects/micronaut-openapi/pull/750

nbrugger-tgm commented 1 year ago

Hi, don't want to be inpatient, and i do not ask for this to be fixed, but it would be very kind to get an answer if this is a bug or working as intended.

dstepanov commented 1 year ago

Can you please create an example project

nbrugger-tgm commented 1 year ago

Sure, sorry for not doing this earlier

here you go: https://github.com/nbrugger-tgm/micronaut-reproductions/ Folder : 6918 (ticket number)

There is a testscript to be executed as soon as the api is started using ./gradlew run called test.sh

This is the most minimal that i managed to produce