CDI/Weld unable to do constructor injection of RESTEasy resource
Asked Answered
M

1

7

I'm trying to combine RESTEasy with Weld on AppEngine but having troubles to do constructor injection.

I've added the RESTEasy CdiInjectorFactory context param and the Weld servlet listener.

My RESTEasy application class looks like:

public class MyApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> classes = new HashSet<Class<?>>();
        classes.add(CustomerResource.class);
        return classes;
    }
}

and the CustomerResource:

@Path("/rest/app/customers")
public class CustomerResource {

    private final CustomerService customerService;

    @Inject
    public CustomerResource(CustomerService customerService) {
        this.customerService = customerService;
    }

    ..
}

The CustomerService is a simple service like:

public class CustomerService {

    public List<Customer> getCustomers() {
        ..
    }
}

When I start up the server I see in the log:

[INFO] 2014-01-30 21:34:53 INFO  org.jboss.weld.Version:146 - WELD-000900: 2.1.2 (Final)
[INFO] 2014-01-30 21:34:53 WARN  org.jboss.weld.environment.servlet.Listener:137 - @Resource injection not available in simple beans
[INFO] 2014-01-30 21:34:54 INFO  org.jboss.weld.Bootstrap:199 - WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
[INFO] 2014-01-30 21:34:55 DEBUG org.jboss.resteasy.cdi.ResteasyCdiExtension:68 - Discovered CDI bean which is javax.ws.rs.core.Application subclass com.mycomp.config.MyApplication.
[INFO] 2014-01-30 21:34:55 DEBUG org.jboss.resteasy.cdi.ResteasyCdiExtension:68 - Bean class com.mycomp.config.MyApplication does not have the scope defined. Binding to @javax.enterprise.context.ApplicationScoped().
[INFO] 2014-01-30 21:34:55 DEBUG org.jboss.resteasy.cdi.ResteasyCdiExtension:68 - Discovered CDI bean which is a JAX-RS resource com.mycomp.rest.app.CustomerResource.
[INFO] 2014-01-30 21:34:55 DEBUG org.jboss.resteasy.cdi.ResteasyCdiExtension:68 - Bean class com.mycomp.rest.app.CustomerResource does not have the scope defined. Binding to @javax.enterprise.context.RequestScoped().
[INFO] 2014-01-30 21:34:55 INFO  org.jboss.weld.environment.servlet.Listener:147 - No supported servlet container detected, CDI injection will NOT be available in Servlets, Filters or Listeners
[INFO] 2014-01-30 21:34:56 WARN  org.jboss.weld.Interceptor:47 - WELD-001700: Interceptor annotation class javax.ejb.PostActivate not found, interception based on it is not enabled
[INFO] 2014-01-30 21:34:56 WARN  org.jboss.weld.Interceptor:47 - WELD-001700: Interceptor annotation class javax.ejb.PrePassivate not found, interception based on it is not enabled

From this logging I can see that my RESTEasy application and the resources class are discovered. Note that I don't see any mention about the CustomerService.

When I access my resource in the browser I get:

[INFO] 2014-01-30 21:47:26 DEBUG org.jboss.resteasy.cdi.CdiInjectorFactory:68 - Using CdiConstructorInjector for class class com.mycomp.config.MyApplication.
[INFO] 2014-01-30 21:47:26 DEBUG org.jboss.resteasy.cdi.CdiConstructorInjector:68 - Beans found for class com.mycomp.config.MyApplication : [Managed Bean [class com.mycomp.config.MyApplication] with qualifiers [@Any @Default]]
[INFO] 2014-01-30 21:47:26 INFO  org.jboss.resteasy.spi.ResteasyDeployment:82 - Deploying javax.ws.rs.core.Application: class com.mycomp.config.MyApplication$Proxy$_$$_WeldClientProxy
[INFO] 2014-01-30 21:47:26 INFO  org.jboss.resteasy.spi.ResteasyDeployment:82 - Adding class resource com.mycomp.rest.app.CustomerResource from Application class com.mycomp.config.MyApplication$Proxy$_$$_WeldClientProxy
[INFO] 2014-01-30 21:47:26 INFO  org.jboss.resteasy.spi.ResteasyDeployment:82 - Adding class resource com.mycomp.rest.HeartbeatResource from Application class com.mycomp.config.MyApplication$Proxy$_$$_WeldClientProxy
[INFO] Jan 30, 2014 9:47:26 PM com.google.appengine.tools.development.ApiProxyLocalImpl log
[INFO] SEVERE: javax.servlet.ServletContext log: unavailable
[INFO] java.lang.RuntimeException: Could not find constructor for class: com.mycomp.rest.app.CustomerResource

Is RESTEasy trying to create a new CustomerResource instance and not picking it from Weld?

I also tried with field injection (instead of constructor injection) and then I can see the CustomerService is nicely injected in the CustomerResource.

I only prefer constructor injection and wonder if this is supported in RESTEasy resource classes when using Weld?

Mydriatic answered 30/1, 2014 at 21:13 Comment(0)
P
13

JAX-RS requires a no arg constructor for your rest resources. You can have other constructors, but you need to also have a no-arg constructor.

Plessor answered 31/1, 2014 at 1:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.