JAX-RS: How to extend Application class to scan packages?
Solution 1
"Is there a specific Java equivalent?"
Simply leave the class empty, meaning do not override getClasses()
or getSingletons()
. Per the spec - 2.3.2:
[...]
In either of the latter two cases, if both
Application.getClasses
andApplication.getSingletons
return an empty list then all root resource classes and providers packaged in the web application MUST be included in the published JAX-RS application. If eithergetClasses
orgetSingletons
return a non-empty list then only those classes or singletons returned MUST be included in the published JAX-RS application.
So you can simply do
@ApplicationPath("oauth")
public class OAuthApplication extends Application {}
and your classpath will get scanned for @Path
and @Provider
classes. Override either method (returning a non-empty set), and only those classes will be added.
It should also be noted that public Map<String, Object> getProperties()
can be safely overridden. You can use this to add arbitrary properties (even to register classes/features), as seen here, or if you need to configure a provider, you can do so in a Feature
or DynamicFeature
as seen here
Solution 2
It is very simple:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/webapi")
public class MyApp extends Application {
}
This will scan all the classes annotated with @Provider and @Path.
Solution 3
Is a combination of all Application class, ResourceClass and @ApplicationPath
in agreement with the docs and the class ResourceConfig implements by jersey the way to do is:
@ApplicationPath(value = "/resource")
public class ApplicationREST extends ResourceConfig {
public ApplicationREST() {
//add single resources
register(SimpleResource1.class);
register(SimpleResource2.class);
...
//enable multipar feature
register(MultiPartFeature.class);
...
//enable scan package and recursive
packages(true, "com.example.rest");
}
}
I hope this helps you
daydreamer
Hello Viewer, Some of the places to see my work are BonsaiiLabs My Website
Updated on June 05, 2022Comments
-
daydreamer almost 2 years
Currently, I do something similar to
import javax.annotation.Nonnull; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import java.util.Collections; import java.util.HashSet; import java.util.Set; @ApplicationPath("oauth") public class OAuthApplication extends Application { final Set<Class<?>> classes = new HashSet<>(); @Nonnull @Override public Set<Class<?>> getClasses() { classes.add(RegisterResource.class); return Collections.unmodifiableSet(classes); } }
No if I add ten new
Resource
s on theApplicationPath
, I need to doclasses.add(<ClassName>.class);
ten times, it is tedious and sometimes forgetful as well.
Does
JAX-RS
orRESTEasy
provide the way so that I can mention the package name and classes are scanned under it?I know
Jersey
has something aspublic class MyApplication extends ResourceConfig { public MyApplication() { packages("org.foo.rest;org.bar.rest"); } }
Any thoughts/ideas?
UPDATE
Seems we can do following in
web.xml
<context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param>
Is there a specific
Java
equivalent? -
Michael Repucci over 7 yearsPerhaps this should be a separate question, but I'm finding that, with the solution suggested here, my JAX-RS application isn't automatically picking up some registered ExceptionMapper providers that reside in a separate EJB package in the EAR, which also contains the WAR. I'd rather not have to explicitly add every class, as the OP indicates, but do need the kind of "add package" shortcut that Jersey provides, and still can't find a way to do this with RESTEasy. Any thoughts?
-
Michael Repucci over 7 yearsSeems like I need a different question because explicitly adding all the classes in an overridden getClasses() method actually doesn't work either. Nor does registering them as a Feature. There must be something special about these ExceptionMapper providers. Hmm...
-
Michael Repucci over 7 yearsMaking a little progress ... the Wildfly logs indicate that one of the exceptions that appears to not be properly handled is an EJBException: ERROR [io.undertow.request] (default task-121) UT005023: Exception handling request to /rest/authenticate: org.jboss.resteasy.spi.UnhandledException: javax.ejb.EJBException: io.jsonwebtoken.ExpiredJwtException. Adding an ExceptionMapper for EJBException does allow me to handle this exception, but I'm not fully understanding why this occurs, when an ExpiredJwtException thrown in my EJB package (rather than the WAR) doesn't exhibit this problem.
-
Michael Repucci over 7 yearsIn the end, my problem was due to how unchecked (System) exceptions get wrapped by the container in an EJBException (see stackoverflow.com/a/19563956/304620). The solution, in my case, was to denote io.jsonwebtoken.ExpiredJwtException in the ejb-jar.xml to make it an Application (checked) exception.
-
Seyed Ali Roshan almost 7 yearsI used it but at first, it gave me 500 for not registering MultiPartFeature and after register it, it gave 404 for all my APIs. any idea?