Martin
Martin

Reputation: 172

A class as Servlet and / or JAX-RS resource in an OSGi environment

Currently I register HttpServlets with my OSGi service registry. These handled by another component and added to a Jetty server on-the-fly. This works very well and I need exactly this procedure for example when using Vaadin or just a plain HttpServlet with some specific functionality.

However, I would like to re-use this approach also for registering Servlets making use of JAX-RS (in my case currently Jersey implementation). My idea was to simply re-use my HttpServlet and add JAX-RS annotations.

Of course this does not work out-of-the-box because annotations are not passed by the OSGi service proxies and the other component or server needs to support this. Therefore I decided for an abstract class extending an HttpServlet to handle the service and pass it to a Jersey ServletContainer. The ServletContainer should then be configured with an Application including the original HttpServlets object as singleton.

It does not seem to work and I don't understand why. The error is:

18:26:02.190 WARN o.g.jersey.internal.inject.Providers - A provider path.to.MyServlet registered in SERVER runtime does not implement any provider interfaces applicable in the SERVER runtime. Due to constraint configuration problems the provider path.to.MyServlet will be ignored.

MyServlet:

@Path("/")
public class MyServlet extends AbstractServlet {

    @GET @Path("/{path}")
    public Response root(@PathParam("path") String path) {
        // ...
    }

}

AbstractServlet:

public abstract class AbstractServlet extends HttpServlet {

    private ServletContainer servletContainer = null;

    public AbstractServlet() {
        this.servletContainer = new ServletContainer(ResourceConfig.forApplication(new ApplicationAdapter(this)));
    }

    @Override
    public void destroy() {
        this.servletContainer.destroy();
    }

    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException,IOException {
        this.servletContainer.service(request, response);
    }

    @Override
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException { 
        this.servletContainer.service(request, response);
    }

    // ... (delegate all methods from HttpServlet to ServletContainer)

    @ApplicationPath("/")
    private class ApplicationAdapter extends Application {

        private final Object object;

        public ApplicationAdapter(final Object object) {
            this.object = object;
        }

        @Override
        public Set<Object> getSingletons() {
            return new HashSet<Object>(Arrays.asList(this.object));
        }

    }
}

Upvotes: 1

Views: 378

Answers (1)

Christian Schneider
Christian Schneider

Reputation: 19606

If you are looking into doing jax-rs on OSGi then you should take a look at Aries JAX-RS whiteboard.

It is the reference impl of the upcoming JAX-RS Whiteboard OSGi spec that will be part of OSGi R7 release. The specs and reference impls should be released in a few weeks.

The documentation and examples are a bit sparse still but it is surely something to watch out for.

Upvotes: 1

Related Questions