kumuluzee
kumuluzee copied to clipboard
Multiple JAX RS in the same uber JAR
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
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>
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 :)
I guess that you can not deploy kumulzee using the traditional pattern, i.e. one JEE server whwre you could deploy multiple WAR:s?
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).