26

I am using JAX-RS for my web services. I have common functionality and would like to use inheritance. I am providing simple CRUD operations. I have defined an interface like so:

public interface ICRUD {

    @POST
    @Consumes("application/json")
    @Produces("application/json")
    @Path("create")
    public String createREST(String transferObject);

    @GET
    @Consumes("application/json")
    @Produces("application/json")
    @Path("retrieve/{id}")
    public String retrieveREST(@PathParam("id") String id);

    @POST
    @Consumes("application/json")
    @Produces("application/json")
    @Path("update")
    public void updateREST(@Suspended final AsyncResponse asyncResponse,
                           final String transferObject) ;

    @DELETE
    @Consumes("application/json")
    @Produces("application/json")
    @Path("delete/{id}")
    public String deleteREST(@PathParam("id") String id); 
}

I have an abstract class that implements this interface:

public abstract class BaseREST implements ICRUD{

private final ExecutorService executorService = Executors.newCachedThreadPool();

@Override
public String createREST(String transferObject) {
    return create(transferObject).toJson();
}

@Override
public String retreiveREST(@PathParam("id") String id) {
    return retreive(id).toJson();
}


@Override
public String deleteREST(
        @PathParam("id") String id) {
    return delete(id).toJson();
}

@Override
    public void updateREST(@Suspended final AsyncResponse asyncResponse, final String transferObject) {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                asyncResponse.resume(doUpdateREST(transferObject));
            }
        });
    }      

}

And lastly, my implementing class simply provides a PATH for the resource:

@Path("meeting")
public class MeetingRestServices extends BaseREST {
}

When I try to access my resource at (assuming the context root is /):

http://localhost:8080/webresources/meeting/retreive/0

I get a 404, it says it can not find it. My thoughts are that somewhere in the inheritance, it is messing with the path of where I think the resource should be. Any thoughts on this?

EDIT

webresources is defined below. This class is added automatically by Netbeans.

@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new java.util.HashSet<>();
        addRestResourceClasses(resources);
        return resources;
    }

    /**
     * Do not modify addRestResourceClasses() method.
     * It is automatically populated with
     * all resources defined in the project.
     * If required, comment out calling this method in getClasses().
     */
    private void addRestResourceClasses(Set<Class<?>> resources) {
        resources.add(com.dv.meetmefor.ws.impl.BinaryDataRestService.class);
        resources.add(com.dv.meetmefor.ws.impl.ImageRestServices.class);
        resources.add(com.dv.meetmefor.ws.impl.LocaleRestService.class);
        resources.add(com.dv.meetmefor.ws.impl.MeetUpRestServices.class);
        resources.add(com.dv.meetmefor.ws.impl.MeetingRestServices.class);
        resources.add(com.dv.meetmefor.ws.impl.UserAccountRestServices.class);
    }

}
Andrea Bergonzo
  • 3,983
  • 4
  • 19
  • 31
user489041
  • 27,916
  • 55
  • 135
  • 204
  • What is `/webresources/`? – Sotirios Delimanolis Sep 18 '14 at 15:31
  • @SotiriosDelimanolis I updated the question to show where that comes from. It looks like Netbeans manages that for some reason I do not fully understand. I will say though, when I implemented this without inheritance, it did work at that URL. – user489041 Sep 18 '14 at 15:34
  • Possibly a duplicate of: https://stackoverflow.com/questions/5875772/staying-dry-with-jax-rs – Zero3 Mar 15 '15 at 02:31

1 Answers1

49

What you've described above looks good. Here are the rules for JAX-RS inheritance which based on what you've provided you are adhering.

From JAX-RS spec §3.6:

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 method and its parameters do not have any JAX-RS annotations of its own. Annotations on a super-class take precedence over those on an implemented interface. If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the super class or interface method are ignored. E.g.:

public interface ReadOnlyAtomFeed {
    @GET @Produces("application/atom+xml")
    Feed getFeed();
}

@Path("feed")
public class ActivityLog implements ReadOnlyAtomFeed {
    public Feed getFeed() {...}
}

In the above, ActivityLog.getFeed inherits the @GET and @Produces annotations from the interface. Conversely:

@Path("feed")
public class ActivityLog implements ReadOnlyAtomFeed {
    @Produces("application/atom+xml")
    public Feed getFeed() {...}
}

In the above, the @GET annotation on ReadOnlyAtomFeed.getFeed is not inherited by ActivityLog .getFeed

dma_k
  • 10,431
  • 16
  • 76
  • 128
cmd
  • 11,622
  • 7
  • 51
  • 61
  • 3
    Had similar issue. The rule "..subclass or implementation method has any JAX-RS annotations then all of the annotations on the super class or interface method are ignored.." helped to find issue: – Ruslan Nov 21 '16 at 12:32
  • 1
    Very useful information. It would be nice to have some link to that spec, however. – Dinei May 18 '17 at 21:04
  • Here's a link for the spec: file:///Users/mmunoz/Downloads/jaxrs-2_1-final-spec.pdf I think this is the most current, as of 6/24/19. – MiguelMunoz Jun 25 '19 at 00:46
  • 6
    Here's what I'm not clear about. The quoted spec has two sentences that look like they contradict each other: "If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the super class or interface method are ignored" is illustrated here. But what do they mean when they say "Annotations on a super-class take precedence over those on an implemented interface"? Here, the implemented interface annotations are taking precedence. Can anyone illustrate this? – MiguelMunoz Jun 25 '19 at 00:49