kumuluzee icon indicating copy to clipboard operation
kumuluzee copied to clipboard

Multiple JAX RS in the same uber JAR

Open helander opened this issue 7 years ago • 4 comments

Is it possible to include several sub-classes of javax.ws.rs.core.Application (each with their own ApplicationPath and resource classes) in the same Kumuluzee uber jar? If so, what are the necessary steps to make that work.

/Lars

helander avatar Nov 01 '17 22:11 helander

As per the JAX-RS specification if the application/microservice includes more then one subclass of javax.ws.rs.core.Application then it won't automatically initialize and set them up. You'll need to do it manually by adding the relevant entries to the web.xml file.

In addition, you'll need to manually specify which resources/providers belong to which JAX-RS application as the framework cannot know that by itself. You can do that by overriding the getClasses method from the javax.ws.rs.core.Application class and returning the classes of all your resources/filters that the specific application uses.

However it seems that if you use JAX-RS and CDI together and try to register two javax.ws.rs.core.Application classes the Jersey JAX-RS implementation does not handle that quite correctly. This issue can be found here:

https://github.com/jersey/jersey/issues/3624

KumuluzEE uses Jersey for JAX-RS and Weld for CDI like it's mentioned on that issue.

It seems that currently they're not planning to support this use case, however we'll look into it and see if this is something that we can add support for and enable.

In the meantime it may be best to use a single application and try and segment on the resource level. Or maybe create two separate applications. If you don't have CDI though it will work ok.

Quick example without CDI:

public class FirstRestApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {

        Set<Class<?>> classes = new HashSet<>();

        classes.add(FirstResource.class);

        return classes;
    }
}
public class SecondRestApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {

        Set<Class<?>> classes = new HashSet<>();

        classes.add(SecondResource.class);

        return classes;
    }
}
resources/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <servlet>
        <servlet-name>com.test.FirstRestApplication</servlet-name>
    </servlet>

    <servlet-mapping>
        <servlet-name>com.test.FirstRestApplication</servlet-name>
        <url-pattern>/first/*</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>com.test.SecondRestApplication</servlet-name>
    </servlet>

    <servlet-mapping>
        <servlet-name>com.test.SecondRestApplication</servlet-name>
        <url-pattern>/second/*</url-pattern>
    </servlet-mapping>

</web-app>

TFaga avatar Nov 02 '17 10:11 TFaga

Again thank you. I already defined the getClasses() in my Application sub-classes. I need to think about my possibilities and pick the best (or least bad). Thanks for sharing the facts :)

helander avatar Nov 02 '17 12:11 helander

I guess that you can not deploy kumulzee using the traditional pattern, i.e. one JEE server whwre you could deploy multiple WAR:s?

helander avatar Nov 02 '17 12:11 helander

Somewhat like that. KumuluzEE while a Java EE framework is geared and build primary for building microservices with said technologies. With microservices you run and deploy each app (i.e. WAR) as a separate service which contains all of it's dependencies and can be ran by itself. Therefor you don't have a single server running multiple applications.

This just means you can run each WAR separately as a standalone service. And because KumuluzEE is very lightweight compared to a traditional application server, it's overhead is very low, making it the recommended approach. You still of course have the flexibility what runs inside and retain the interoperability with there rest of the Java EE ecosystem (traditional patterns or otherwise).

TFaga avatar Nov 05 '17 16:11 TFaga