1

How to declare multiple packages in the web.xml for the RESTEasy jax-rs provider?

If I have:

enter image description here

 <web-app id="WebApp_ID" version="2.4"
        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_2_4.xsd">
        <display-name>Restful Web Application</display-name>

    <!-- this need same with resteasy servlet url-pattern -->
        <context-param>
            <param-name>resteasy.servlet.mapping.prefix</param-name>
            <param-value>/rest</param-value>
        </context-param>

        <servlet>
            <servlet-name>resteasy-servlet</servlet-name>
            <servlet-class> org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher </servlet-class>
            <init-param>
                <param-name>javax.ws.rs.Application</param-name>
                <param-value>part1.MessageApplication</param-value>
            </init-param>
        </servlet>

        <servlet-mapping>
            <servlet-name>resteasy-servlet</servlet-name>
            <url-pattern>/rest/*</url-pattern>
        </servlet-mapping>
    </web-app>

It's working.

But If I have :

enter image description here

And then change the declaration of the web.xml (which is based on this way, which may have already worked in Jersey)

<servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class> org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher </servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>part1.MessageApplication;part2.MessageApplication2</param-value>
        </init-param>
    </servlet>

Whenever I try to access a @Path-mapped-class in package "part2" it will throw :

java.lang.RuntimeException: java.lang.ClassNotFoundException: part1.MessageApplication;part2.MessageApplication2 from

Note that I'm aware that I've changed the @Path-mapped-class with different url path like @Path("controller2").

How do I configure it properly in the web.xml?

Community
  • 1
  • 1

1 Answers1

4

Not sure if I clearly understand your problem. The link you provided in your question is about specifying multiple packages. But looks like you are dealing with two Application subclasses. It's a different matter.

In this situation, you should register two HttpServletDispatcher mapped to different URI patterns, as following:

<!-- Application 1 (part1.MessageApplication) mapped to /rest/app1/* -->
<servlet>
    <servlet-name>resteasy-application1</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>part1.MessageApplication</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>resteasy-application1</servlet-name>
    <url-pattern>/rest/app1/*</url-pattern>
</servlet-mapping>

<!-- Application 2 (part2.MessageApplication2) mapped to /rest/app2/* -->
<servlet>
    <servlet-name>resteasy-application2</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>part2.MessageApplication2</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>resteasy-application2</servlet-name>
    <url-pattern>/rest/app2/*</url-pattern>
</servlet-mapping>

Each Application subclass is mapped to a path that serves as the base URI for the resource URIs provided by @Path annotation.

You could have multiple Application subclasses when you support multiple versions of the API, for example. For simple applications, it's very likely you don't need that.

You may not need a web.xml

As per your comment, you are using WildFly 8. It's Servlet 3.0 compatible so you don't even need a web.xml deployment descriptor for simple applications. Most of the configurations, such as registering servlets, filters and listeners can be done via annotations.

In case you are not providing a web.xml deployment descriptor for your Maven-based web application project, you need to configure your maven-war-plugin to ignore the missing web.xml file by setting the failOnMissingWebXml configuration property to false in your project pom.xml file:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
</plugin>

Since the version 3.0.0 of the maven-war-plugin, the default value for failOnMissingWebXml has been changed from true to false. You can use the most recent version and ommit that configuration property.

If, for some reason, you want to keep the web.xml, it can be as simple as:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
          version="3.0">

</web-app>

A few words on the Application class

Regarding JAX-RS, annotate your Application subclass with @ApplicationPath specifying the base URI for your resource classes:

@ApplicationPath("api")
public SampleApplication extends Application {

}

In the example above, the JAX-RS runtime will scan the classpath for JAX-RS components and will register them automatically.

If you want to manually register your resources and providers (preventing the JAX-RS runtime from registering the components automatically), override the getClasses() and/or the getSingletons() methods:

@ApplicationPath("api")
public SampleApplication extends Application {

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

For more details on the Application class, this answer can provide you some insights.

Managing your dependencies

It's worthwhile to mention that RESTEasy 3.x is shipped with WildFly. If you will use only the JAX-RS API the following dependency will give you all you need:

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
</dependency>

If you need to use any type from the RESTEasy API, add the RESTEasy 3.x dependencies with the provided scope. It tells Maven that the container will provide that dependency, hence they won't be shipped with your application. Failing to provide the right scope may cause some weird errors and bad headaches. For more details on scopes, check the dependency scope documentation.

Community
  • 1
  • 1
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • Thanks, btw, ya that's exactly what my question is `2 Application subclasses` *in different packages*, btw since I'm newbie in jax-rs overall, do you use only single `javax.ws.rs.core.Application` for across multiple controllers/services, or just use one? .I'll try your suggestion later, i'm outside now. – Plain_Dude_Sleeping_Alone Apr 20 '17 at 08:34
  • 1
    @Hey-men-whatsup It depends on what you are trying to achieve. I usually have multiple `Application` subclasses when I am supporting multiple versions of the API, for example. For simple applications, you don't need that. Each `Application` subclass is mapped to a path that serves as the base URI for all resource URIs provided by `@Path` annotation. – cassiomolin Apr 20 '17 at 08:36
  • Btw If I recall I've tried that before for the rest of my life, but somehow it behaves different in RESTEasy. – Plain_Dude_Sleeping_Alone Apr 20 '17 at 08:37
  • @Hey-men-whatsup What container are you using? – cassiomolin Apr 20 '17 at 08:42
  • Wildfly 8.0.., with single dependency `resteasy-jaxrs-2.2-1.GA.jar`, though, i must admit, the container itself is kinna painful :D – Plain_Dude_Sleeping_Alone Apr 20 '17 at 08:44
  • @Hey-men-whatsup You don't even need a `web.xml` for deploying web applications in WildFly 8. It's Servet 3.x compatible. – cassiomolin Apr 20 '17 at 08:47
  • 1
    @Hey-men-whatsup For more details on the `Application` class, refer to this [answer](http://stackoverflow.com/a/42077836/1426227). I will update my answer with some details that can point you to a good direction. – cassiomolin Apr 20 '17 at 08:52