eclipse-ee4j / jersey

Eclipse Jersey Project - Read our Wiki:
https://github.com/eclipse-ee4j/jersey/wiki
Other
681 stars 339 forks source link

Incosistent handling of inherited @Produces annotations #5672

Closed splatch closed 1 month ago

splatch commented 1 month ago

Since a while I been using a quite dummy way to force specific jaxrs output:

import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public interface BasicResource {

}

Path("/audit")
public class AuditResource implements BasicResource {

  @GET
  public List<AuditEntry> getAll(@QueryParam("page") @DefaultValue("1") long page,
    @QueryParam("size") @DefaultValue("20") long size,
    @QueryParam("kind") String kind
  ) {
    return Collections.emptyList();
  }
}

The basic call curl 'http://localhost:8080/audit' -H 'Accept: */*' results in an error:

! org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=text/plain, type=class java.util.ArrayList, genericType=java.util.List<AuditEntry>.

When I change implements to extends, it starts to work, which is quite strange because I could have swear that such way worked with jersey (1.x or 2.x) and cxf before. Issue happens with dropwizard, which to my knowledge does very little above jersey. I've confirmed this behavior is present in 3.0.12 and 3.0.14 releases.

jansupol commented 1 month ago

From the Spec perspective, the annotation inheritance as in the example above should not work:

JAX-RS annotations may be used on the methods and method parameters of a super-class or an implemented interface. Such annotations are inherited by a corresponding sub-class or implementation class method provided that the method and its parameters do not have any JAX-RS annotations of their own. Annotations on a super-class take precedence over those on an implemented interface. The precedence over conflicting annotations defined in multiple implemented interfaces is implementation specific. Note that inheritance of class or interface annotations is not supported.

Only annotations on methods should be inherited, not on the class/interface.

splatch commented 1 month ago

Thank you for clarification and citation. Given it is behavior defined by spec I must have lived under wrong impression.