3

I've found conflicting answers to this question and I've failed to successfully run an example.

Can JAX-RS be implemented using Servlet 3.0 (in particular, Tomcat 7) with annotations, only, without having to implement another Servlet Container?

If no, please explain why the following quote from this book is either, incorrect or I'm interpreting it, wrong.

Because this example deploys within a Java EE application server or standalone Servlet 3.x container, all we need is an empty web.xml file. The server will detect that an Application class is within your WAR and automatically deploy it. (RESTful Java with JAX-RS 2.0, Bill Burke)

To clarify what I don't need help with... I've, successfully, implemented JAX-RS in Tomcat 7 with Jersey using a web.xml, so, I don't need any explanation of how to do so. Also, I'm fully aware that other Java EE/Servlet Containers (TomEE, Glassfish, Jersey, Websphere, etc...) are all JAX-RS aware out of the box. I just need to know if I'm chasing my tail trying to get Tomcat 7 (Servlet 3.0) to work with JAX-RS without adding a Servlet Container and without web.xml entries.

Lee Duckworth
  • 240
  • 4
  • 15

1 Answers1

7

In a Servlet environment, Jersey runs as a servlet or servlet filter. No way around that. So how does it work without declaring it in the web.xml? Two main components to this functionality

  • Programmatic registration of Servlet components (i.e. servlets and fitlers). You can do a Google search, and you should find some hits of examples.

  • Servlet pluggability introduced in Servlet 3.x. How it works is you implement a ServletContainerInitializer, list that implementation in a file named javax.servlet.ServletContainerInitializer, and put that file in the META-INF/services directory of the jar. The servlet container should scan jars looking for this file. When it finds on, it sees the implementation, finds the implementation, instantiates it, then calls it onStartup method.

    Jersey has such an implementation of the SevletContainerInitializer in the JerseyServletContainerInitializer. This class is located in the jersey-container-servlet jar. So you need this jar for this to work. If you look at this method, this is where you will see the programmatic registration of the ServletContainer (the same one that yo would declare in the web.xml

But that's not all. We still need some way of configuring our application, at the least declare the servlet mapping. That's where the Application class and the @ApplicationPath annotation come in. We would extend the Application class and and annotate the @ApplicationPath("/path") where "path" is the same as the servlet mapping in the web.xml

@ApplicationPath("/api")
public class MyApplication extends Application {}

This is standard JAX-RS. With Jersey normally instead of an Application class, we use a ResourceConfig class (which is a subclass of Application)

@ApplicationPath("/api")
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        packages("package.to.scan");
    }
}

You can see more about Jersey deployment options in a Servlet 3.x environment, here.

It should also be noted, that a Java EE server has the JAX-RS implementation, so we only need to add the javaee-api jar to our application as provided dependency. But in a servlet container, we need to provide our own implementation, Jersey being such an implementation.

If you are using Maven, the main dependency you'll need is this one

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>${jersey2.version}</version>
</dependency>

This will pull a bunch of other jars in. You you aren't using Maven, then you can download all the jars here (the JAX-RS 2.0 RI bundle), and put all those into your application.

See Also:

escitalopram
  • 3,750
  • 2
  • 23
  • 24
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Thanks for your time. I want to know if I can deploy this in Tomcat 7 (Servlet 3.0) WITHOUT Jersey or web.xml entries. Some references say that all you need is for JAX-RS to work is JavaEE OR Servlet 3.0.... with no mention of Servlet Containers/Initializers (apart from javax.ws.rs.core.Application). If a servlet container/initializer is still required in Servlet 3.0 then, the book and the references that I've read are wrong. Are you sure that you're not refering to Tomcat prior to Servlet 3.0? – Lee Duckworth Oct 22 '15 at 20:54
  • 1
    No you can't without a JAX-RS implementation. Only Java EE servers come equipped with JAX-RS. Tomcat doesn't. JAX-RS is part of the Java EE specification. Tomcat is not an EE compliant server. It only has support for parts of the spec like servlets and jsp. Other features of the spec, we need to add ourselves, such as JAX-RS (which itself is only a specification) by adding an implementation of it (such as Jersey or RESTeasy) – Paul Samsotha Oct 22 '15 at 20:55
  • Ok. So, in the example in the book that I was referring to, there is only a class that extends javax.ws.rs.core.Application and the resource classes are appended. There is only a blank web.xml and no servlet containers included (i.e. Jersey). The following text is as I quoted, above: "Because this example deploys within a Java EE application server or standalone Servlet 3.x container, all we need is an empty web.xml file. The server will detect that an Application class is within your WAR and automatically deploy it." According to what you're telling me, the book is wrong? – Lee Duckworth Oct 22 '15 at 21:01
  • 1
    Look at the dependencies from the example project. It might include a RESTeasy dependency. The author of the book is the creator of RESTeasy, which is a JAX-RS implementation. The only way the example will work if is it has the `resteasy-servlet-initializer` dependency. If not it won't run in Tomcat. That dependency contains RESTeasy's implementation of the `ServletContainerInitializer` – Paul Samsotha Oct 22 '15 at 21:05
  • 2
    You will need Maven to run the examples. If don't know Maven, then you are not going to be able to run the examples. All the dependencies are the `pom.xml` file. When you build the project with Maven, Maven pulls in all the jars. I am looking at the example projects right now and yes they do include RESTeasy as dependencies in the pom.xml file. So that is the JAX-RS implementation the examples are using – Paul Samsotha Oct 22 '15 at 21:10
  • Awesome! RESTeasy is what was missing from the explanation of the example. Thanks!!! – Lee Duckworth Oct 22 '15 at 21:21
  • Page 10 of the book does explain that the examples need to be ran with RESTeasy. That's what I get for skipping pages! Thanks for your help!!! – Lee Duckworth Oct 22 '15 at 21:39