Hi guys I am new to rest and jax-rs so my question is every rest service starts with extending that application class and defining applicationpath. Now my question is what is the lifecyce of that application class itself? Here is an example:
import javax.ws.rs.core.Application;
@javax.ws.rs.ApplicationPath("resources")
public class ApplicationConfig extends Application {}
Is this a servlet? Is it always alive? How shall I understand this class? Is it a cdi bean? Does the server creates this class on every request?
What is Application
?
Application
is a deployment agnostic abstract class provided by JAX-RS for configuring and registering the components of a JAX-RS application and it's also used to supply additional metadata to the application.
Application
is one of the types that can be injected using the @Context
annotation. For more details, refer to this answer.
Subclasses of Application
Application
subclasses can implement methods such as getClasses()
, getSingletons()
and getProperties()
for configuring and registering components and properties.
Application
subclasses can be annotated with @ApplicationPath
, defining the base URI for the JAX-RS resource classes (classes annotated with @Path
). Application
subclasses are instantied once when the web application starts and they are managed by the JAX-RS runtime.
The simplest implementation possible is as following:
@ApplicationPath("api")
public SampleApplication extends Application {
}
In the example above no resources classes or providers are registered, so the JAX-RS runtime will scan the classpath for JAX-RS components and will register them automatically.
However, according to this post from Jakub Podlesak, this approach is discouraged in production environments:
The above example works great. When started, the application just scans the actual class-path, and adds every single JAX-RS component class found there to the actual runtime configuration. Isn't is great? Frankly, this kind of configuration could work just fine. Until someone changes either the system configuration (system class-path) or the way how you application is being packaged (a new 3rd party component could be added/removed from the application class-path then). These changes could be out of your control and if one of them happens, you application configuration could break. For this reason, it is not wise to use this kind of configuration in a production environment.
Jersey, the JAX-RS reference implementation, provides the ResourceConfig
class. Compared to Application
, ResourceConfig
provides advanced capabilities to simplify registration of JAX-RS components, such as scanning for root resource and provider classes in a provided classpath or a in a set of package names, etc. For more details, refer to the Jersey documentation.
Working with multiple Application
subclasses
Is also worth mentioning that you are not restricted to a single Application
subclass per web application. The same WAR can have multiple Application
subclasses. For more details, have a look at this post from Adam Bien:
To deploy multiple JAX-RS applications with different URIs in one WAR you will have to create one javax.ws.rs.core.Application
subclass per such an application (or use web.xml
for this purpose). Obviously the in Java EE ubiquitous Convention over Configuration (or Configuration by Exception) cannot work any more: you will have to explicitly configure resources in each subclass by overriding the method getClasses
or getSingletons
:
@Path("first")
public class FirstResource {
@GET
public String first() {
return "first";
}
}
@ApplicationPath("one")
public class JAXRSConfigurationOne extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new HashSet<>();
resources.add(FirstResource.class);
return resources;
}
}
@Path("second")
public class SecondResource {
@GET
public String first() {
return "second";
}
}
@ApplicationPath("two")
public class JAXRSConfigurationTwo extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new HashSet<>();
resources.add(SecondResource.class);
return resources;
}
}
Both JAX-RS applications become accessible through distinct URIs: http://localhost:8080/multiple-roots/one/first
and http://localhost:8080/multiple-roots/two/second
What if no Application
subclass is present?
If no Application
subclass is present, the JAX-RS implementations are required to add a servlet and set its name to javax.ws.rs.Application
and to automatically discover all resource classes and providers which must be packaged with the application.
For further details, have a look at the chapter 2 of the JAX-RS 2.1 specification.