helidon-io / helidon

Java libraries for writing microservices
https://helidon.io
Apache License 2.0
3.51k stars 566 forks source link

4.x - ApplicationPath is not a bean defining annotation #8502

Open romain-grecourt opened 7 months ago

romain-grecourt commented 7 months ago

Environment Details

Problem Description

@Path is a bean defining annotation but @ApplicationPath is not. When creating a JaxRs application annotated only with @ApplicationPath but not with @ApplicationScope it is discarded.

This can lead to incorrect behavior:

Both @Path and @Provider are declared as bean defining annotations, most likely for convenience.

Is it an oversight that @ApplicationPath is not included ?

Steps to reproduce

public class Main {
    public static void main(String[] args) {
        io.helidon.Main.main(args);
    }

    @ApplicationPath("/")
    public static class App1 extends Application {

        @Override
        public Set<Class<?>> getClasses() {
            return Set.of(Resource.class);
        }

        @Path("/app1")
        public static class Resource {

            @GET
            public String get() {
                return "OK";
            }
        }
    }

    @ApplicationPath("/foo")
    public static class App2 extends Application {

        @Override
        public Set<Class<?>> getClasses() {
            return Set.of(Resource.class);
        }

        @Path("/app2")
        public static class Resource {

            @GET
            public String get() {
                return "OK";
            }
        }
    }
}
curl  http://localhost:8080/app2
OK
curl  http://localhost:8080/foo/app2
Not Found
tomas-langer commented 7 months ago

ApplicationPath cannot be a bean defining annotation, as it is not required on an application. If we made it BDA, some applications would be picked up, some would be ignored, and that is quite a bad behavior. In general application class without a BDA should be ignored (and it should be @ApplicationScoped, as nothing else makes sense)

jefrajames commented 6 months ago

There is an ambiguity with Helidon 4.0.7 when defining a RestApplication class annotated with ApplicationPath. Not adding ApplicationScoped explicitely leads to an inconstency:

. the ApplicationPath value is taken into account by OpenApi when exposing the API documentation . but it is not taken into account in real endpoints exposure.

So endpoints exposed by OpenApi (and ui) are not correct.

romain-grecourt commented 4 months ago

We have agreed on making @ApplicationPath a BDA, and warning about applications not annotated with @ApplicationScoped.

We should also investigate using the Jandex index to detect application classes with no annotations.

tjquinno commented 4 months ago

Some background that might be useful...

The Helidon OpenAPI implementation layers on the SmallRye OpenAPI library.

Helidon's MP OpenAPI code finds out what applications Helidon has discovered (by invoking Helidon's JaxRsCdiExtension#applicationsToRun).

Helidon then asks the SmallRye library to create a separate OpenAPI model for each separate application. Helidon then merges the separate per-application OpenAPI models into a single server-wide model (using a SmallRye utility operation) which gives rise to the single OpenAPI document output at the /openapi endpoint which describes the entirety of the API presented to the outside world by the server and all of its constituent applications.