How to deploy a JAX-RS application?

70,339

Solution 1

There are a number of options for deploying into a Java EE 6 container (more specifically a Servlet 3.0 implementation):

The simplest is:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd" version="3.0">
    <servlet>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

Then all the @Path and @Provider classes found in your web application will be available in the "default" JAX-RS application with a servlet URL pattern of "/rest/*".

If you have one or more classes that extends javax.ws.rs.core.Application, you can specify like so:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd" version="3.0">
    <servlet>
        <servlet-name>com.example.jaxrs.MyApplication</servlet-name>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>com.example.jaxrs.MyApplication</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

You may want to do the above in case you wish to only return specific sets of @Path/@Provider classes on a URL (so you could have a second MyApplication2 with a different URL pattern above).

You can also skip the whole web.xml altogether and just annotate your MyApplication class wih @ApplicationPath which will serve as the URL pattern. I would recommend keeping the web.xml in any case because you will probably have to add other information about the web application there anyway.

If you're wondering where the servlet-class comes from, it is automatically added in by the environment. You can get an idea by looking at the Servlet 3.0 ServletContext.

Solution 2

With WAS 8.5, I change the web.xml to add:

<servlet>
    <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.tada.rest.RestApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
<servlet-mapping>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

My RestApplication look like :

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

public class RestApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> sets = new HashSet<Class<?>>();
        sets.add(RestService.class);
        return sets;
    }
}

My RestService looks like

@Path("/tada")
public class RestService {
    @GET
    public String getSomething() {
        return "tada";
    }
}

And I add in the pom.xml the dependency:

<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.0</version>
</dependency>

Solution 3

With Servlet3.0, follow this. This works for me.

<servlet>
    <description>JAX-RS Tools Generated - Do not modify</description>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>your.restsrv.config.RESTConfig</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <enabled>true</enabled>
    <async-supported>false</async-supported>
</servlet>
<servlet>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
Share:
70,339
deamon
Author by

deamon

Updated on August 30, 2020

Comments

  • deamon
    deamon over 3 years

    The JAX-RS 1.1 specification says on page 6:

    If no Application subclass is present the added servlet MUST be named:

    javax.ws.rs.core.Application
    

    What is the added servlet? Could it be an arbitrary servlet?

    If an Application subclass is present and there is already a servlet defined that has a servlet initialization parameter named:

    javax.ws.rs.Application
    

    Again, what is "a servlet" here?

    If an Application subclass is present that is not being handled by an existing servlet then the servlet added by the ContainerInitializer MUST be named with the fully qualified name of the Application subclass.

    Does "the servlet added by the ContainerInitializer" mean that the servlets is added automatically? How would a configuration look like?

    At the moment I use neither an Application class nor a web.xml and it works (with GlassFish 3.1). Does this deployment mechanism require a full class path scan, which could be slow with big libraries?

    How to deploy on a Servlet container?

    There is a confusing number of configuration options around in the web. See this example with context params in the web.xml (doesn't work for me!). What is the preferred way to deploy a JAX-RS application?

  • Vishrant
    Vishrant over 10 years
    I am getting Broken Link: com.ibm.websphere.jaxrs.server.IBMRestServlet I can not find jar that contains this class, where I can find this jar
  • V G
    V G about 10 years
    That is NOT CORRECT. JAX-RS DOES specify how an JAX-RS application is to be published in a Servlet container in a portable way in the Chapter Applications/Publication/Servlet. Besides, it allows implementations to provide other facilities to deploy.
  • nacho4d
    nacho4d about 8 years
    I was getting messages in eclipse Error 404: javax.servlet.UnavailableException: SRVE0200E: Servlet [com.ibm.websphere.jaxrs.server.IBMRestServlet]: Could not find required class - com.ibm.websphere.jaxrs.server.IBMRestServlet Removing the servlet-class from web.xml as this answer fixed it!. Thanks
  • Alkanshel
    Alkanshel almost 8 years
    How can your web.xml be so minimal without a "resteasy.scan" property set to "true", so that it will automatically find the relevant resources? Wouldn't you still have to list out all your resources in web.xml?
  • Bryant Luk
    Bryant Luk almost 8 years
    @Amalgovinus Depending on the servlet container environment you use and the runtime, you don't have to have specific runtime properties set. This is the standard Java EE JAX-RS deployment configuration as specified in the Java EE spec.
  • Alkanshel
    Alkanshel almost 8 years
    If web.xml is essentially empty, would you then need to manually specify all the possible resources in your class that extends Application?
  • Hervian
    Hervian almost 8 years
    In case other are wondering about the answer's reference to ServletContext I think it hints towards addServlet(). Tomcat-Jersey Example: Tomcat scans the classpath jars and finds a (Jersey)ServletContainerInitializer registered in META-INf/services. The implementation is initialized and onStartup(...) is called. This method constructs Jerseys ServletContainer, and registers it with Tomcat by callling servletContext.addServlet(...). When its init() method is called it retrieves the Application impl. and (I assume) do the scan. It can now map URLs to the @Path annotated methods.
  • Bryant Luk
    Bryant Luk almost 8 years
    @Amalgovinus Depending on your container environment, you may or may not have to do that. Unfortunately I can't be more specific since various combinations of web containers with JAX-RS runtimes can support different setups. My answer is for the standard specification which should be interoperable across Java EE spec-compliant implementations. Like the first example of the web.xml in the answer, some form of class scanning may be done for any annotated Path resources automatically. You only have to specify the servlet-mapping.
  • Bryant Luk
    Bryant Luk almost 8 years
    @Hervian Yup, sorry for being ambiguous there (though I admit I had to refresh my own memory for this since it's been a few years). Servlets can be added pretty much like how you described (or filters and listeners). It's a powerful feature which comes with all that great responsibility too. :)
  • Maarten Seghers
    Maarten Seghers about 6 years
    THANK YOU! Ik had to backport some functionality and this approach worked