Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAX-RS Application subclass injection

I'm writing custom JAX-RS 2.0 application (under Jersey 2.3.1) which holds some data for use by all the resources.

public class WebApp extends org.glassfish.jersey.server.ResourceConfig {
    public WebApp() {
        packages("my.resources.package");
    }
}

(I could use API's javax.ws.rs.core.Application as well, the described result is the same)

Then I inject the object into a resource

@Path("test")
public class Test {
    @Context
    Application app;

    @GET
    @Path("test")
    public String test() {
        return "Application class: " + app.getClass();
    }
}

However, the result of a call is

Application class: class org.glassfish.jersey.server.ResourceConfig$WrappingResourceConfig

which makes me use some ugly tricks like

if (app instanceof WebApp) {
    return (WebApp) app;
} else if (app instanceof ResourceConfig) {
    return (WebApp) ((ResourceConfig) app).getApplication();
}

My understanding of JAX-RS 2.0 spec section 9.2.1:

The instance of the application-supplied Application subclass can be injected into a class field or method parameter using the @Context annotation. Access to the Application subclass instance allows configuration information to be centralized in that class. Note that this cannot be injected into the Application subclass itself since this would create a circular dependency.

is that application-supplied Application subclass is mine WebApp, not JAX-RS implementation-specific wrapper.

Also, changing this fragment

    @Context
    Application app;

to this

    @Context
    WebApp app;

causes app to be null, due to ClassCastException during context injection, so the declared type doesn't matter.

Is it a bug in Jersey or my misunderstanding?

UPDATE: I checked the behaviour under RESTEasy 3.0. The injected object is my WebApp, without any wrappers. I'd call it a bug in Jersey.

like image 645
pwes Avatar asked Nov 14 '13 20:11

pwes


People also ask

What is a JAX-RS application?

JAX-RS is a Java programming language API designed to make it easy to develop applications that use the REST architecture. The JAX-RS API uses Java programming language annotations to simplify the development of RESTful web services.

What is an implementation of JAX-RS specification?

While JAX-RS provides a faster way of developing web applications than servlets, the primary goal of JAX-RS is to build RESTful services. A server-side component API is defined in jaxrs-1.1 and jaxrs-2.0 to build REST applications. IBM® JAX-RS provides an implementation of the JAX-RS (JSR 311) specification.


1 Answers

This doesn't seem like a bug. According to JAX-RS 2.0 spec you can inject Application into your resource classes (for example) but it does not say anything about directly injecting custom extensions of the Application. Not sure what your use-case is but you can register custom HK2 binder that will allow you to inject directly WebApp into resources:

public class WebApp extends org.glassfish.jersey.server.ResourceConfig {
    public WebApp() {
        packages("my.resources.package");

        register(new org.glassfish.hk2.utilities.binding.AbstractBinder() {
            @Override
            protected void configure() {
                bind(WebApp.this);
            }
        });
    }
}
like image 79
Michal Gajdos Avatar answered Oct 28 '22 09:10

Michal Gajdos