JAX-RS: How to extend Application class to scan packages?

daydreamer picture daydreamer · Nov 3, 2014 · Viewed 11.7k times · Source

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 Resources on the ApplicationPath, I need to do

    classes.add(<ClassName>.class);

ten times, it is tedious and sometimes forgetful as well.

Does JAX-RS or RESTEasy provide the way so that I can mention the package name and classes are scanned under it?

I know Jersey has something as

public class MyApplication extends ResourceConfig {
    public MyApplication() {
        packages("org.foo.rest;org.bar.rest");
    }
}

Reference

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?

Answer

Paul Samsotha picture Paul Samsotha · Apr 30, 2015

"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 and Application.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 either getClasses or getSingletons 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