2 Replies Latest reply on Oct 28, 2011 3:40 PM by arendvr.com

    EJB with constructor injection not working in servlet

    arendvr.com

      Hi,

       

      when trying out CDI dependency injection with JBoss 7.0.2, I ran into some problems with constructor injection. Here's one:

       

      These are my classes (see code below):

      1. InjectedServlet - a servlet that uses an injected EJB
      2. GreeterEjb - an EJB with constructor injection
      3. Greeter - a very simple example class

       

       

      When I call the servlet, I get an Exception "WELD-000033 Could not instantiate client proxy for Session bean" (see stacktrace below).

       

       

      • If GreeterEjb uses field injection or method injection instead of constructor injection, it works fine.
      • If I add an additional no-argument constructor to GreeterEjb, it works fine. I don't think the additional no-argument constructor is actually used to instantiate the GreeterEjb, because when the servlet calls it, the dependency is injected properly.
      • If I make GreeterEjb a non-EBJ by removing the @Stateless annotation, it works fine.

       

      I find this quite confusing. Any ideas why constructor injection would not work in this example? Am I missing something?

       

       

      {code}

      @WebServlet(urlPatterns = "/injectedservlet")

      public class InjectedServlet extends HttpServlet {

       

          @Inject

          private GreeterEjb greeterEjb;

       

       

          @Override

          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {

              PrintWriter out = resp.getWriter();

              out.write(greeterEjb.greet());

              out.close();

          }

      }

       

      // comment @Stateless annotation and the servlet works fine

      @Stateless

      public class GreeterEjb {

       

          private Greeter greeter;

       

       

          @Inject

          public GreeterEjb(Greeter greeter) {

              this.greeter = greeter;

          }

       

       

          // un-comment this no-argument constructor and the servlet works fine

      //    protected GreeterEjb() {

      //    }

       

       

          public String greet() {

              return greeter.greet();

          }

      }

       

      public class Greeter {

       

          public String greet() {

              return "Hello, World!";

          }

      }

       

       

      javax.servlet.ServletException: Error instantiating servlet class com.example.ejbconstructorinjection.InjectedServlet

          org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:139)

          org.jboss.as.web.NamingValve.invoke(NamingValve.java:57)

          org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

          org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)

          org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)

          org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:667)

          org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:952)

          java.lang.Thread.run(Unknown Source)

       

      root cause

       

      java.lang.IllegalStateException: Failed to construct component instance

          org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:154)

          org.jboss.as.ee.component.BasicComponent.createInstance(BasicComponent.java:77)

          org.jboss.as.web.deployment.component.WebComponentInstantiator$1.<init>(WebComponentInstantiator.java:57)

          org.jboss.as.web.deployment.component.WebComponentInstantiator.getReference(WebComponentInstantiator.java:55)

          org.jboss.as.web.deployment.WebInjectionContainer.instantiate(WebInjectionContainer.java:99)

          org.jboss.as.web.deployment.WebInjectionContainer.newInstance(WebInjectionContainer.java:78)

          org.jboss.as.web.deployment.WebInjectionContainer.newInstance(WebInjectionContainer.java:72)

          org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:139)

          org.jboss.as.web.NamingValve.invoke(NamingValve.java:57)

          org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

          org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)

          org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)

          org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:667)

          org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:952)

          java.lang.Thread.run(Unknown Source)

       

      root cause

       

      org.jboss.weld.exceptions.WeldException: WELD-000033 Could not instantiate client proxy for Session bean [class com.example.ejbconstructorinjection.GreeterEjb with qualifiers [@Any @Default]; local interfaces are [GreeterEjb]

          org.jboss.weld.bean.SessionBean.create(SessionBean.java:349)

          org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:67)

          org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:693)

          org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:775)

          org.jboss.as.weld.injection.InjectableField.inject(InjectableField.java:62)

          org.jboss.as.weld.injection.WeldEEInjection.inject(WeldEEInjection.java:79)

          org.jboss.as.weld.injection.WeldInjectionInterceptor.processInvocation(WeldInjectionInterceptor.java:60)

          org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:287)

          org.jboss.as.ee.component.ManagedReferenceInterceptor.processInvocation(ManagedReferenceInterceptor.java:53)

          org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:287)

          org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53)

          org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:287)

          org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45)

          org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:287)

          org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)

          org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:152)

          org.jboss.as.ee.component.BasicComponent.createInstance(BasicComponent.java:77)

          org.jboss.as.web.deployment.component.WebComponentInstantiator$1.<init>(WebComponentInstantiator.java:57)

          org.jboss.as.web.deployment.component.WebComponentInstantiator.getReference(WebComponentInstantiator.java:55)

          org.jboss.as.web.deployment.WebInjectionContainer.instantiate(WebInjectionContainer.java:99)

          org.jboss.as.web.deployment.WebInjectionContainer.newInstance(WebInjectionContainer.java:78)

          org.jboss.as.web.deployment.WebInjectionContainer.newInstance(WebInjectionContainer.java:72)

          org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:139)

          org.jboss.as.web.NamingValve.invoke(NamingValve.java:57)

          org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

          org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)

          org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)

          org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:667)

          org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:952)

          java.lang.Thread.run(Unknown Source)

       

      root cause

       

      java.lang.InstantiationException: com.example.ejbconstructorinjection.GreeterEjb$Proxy$_$$_Weld$Proxy$

          java.lang.Class.newInstance0(Unknown Source)

          java.lang.Class.newInstance(Unknown Source)

          org.jboss.weld.util.reflection.SecureReflections$16.work(SecureReflections.java:395)

          org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:54)

          org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInstantiation(SecureReflectionAccess.java:216)

          org.jboss.weld.util.reflection.SecureReflections.newInstance(SecureReflections.java:390)

          org.jboss.weld.bean.SessionBean.create(SessionBean.java:338)

          org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:67)

          org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:693)

          org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:775)

          org.jboss.as.weld.injection.InjectableField.inject(InjectableField.java:62)

          org.jboss.as.weld.injection.WeldEEInjection.inject(WeldEEInjection.java:79)

          org.jboss.as.weld.injection.WeldInjectionInterceptor.processInvocation(WeldInjectionInterceptor.java:60)

          org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:287)

          org.jboss.as.ee.component.ManagedReferenceInterceptor.processInvocation(ManagedReferenceInterceptor.java:53)

          org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:287)

          org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53)

          org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:287)

          org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45)

          org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:287)

          org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)

          org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:152)

          org.jboss.as.ee.component.BasicComponent.createInstance(BasicComponent.java:77)

          org.jboss.as.web.deployment.component.WebComponentInstantiator$1.<init>(WebComponentInstantiator.java:57)

          org.jboss.as.web.deployment.component.WebComponentInstantiator.getReference(WebComponentInstantiator.java:55)

          org.jboss.as.web.deployment.WebInjectionContainer.instantiate(WebInjectionContainer.java:99)

          org.jboss.as.web.deployment.WebInjectionContainer.newInstance(WebInjectionContainer.java:78)

          org.jboss.as.web.deployment.WebInjectionContainer.newInstance(WebInjectionContainer.java:72)

          org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:139)

          org.jboss.as.web.NamingValve.invoke(NamingValve.java:57)

          org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

          org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)

          org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)

          org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:667)

          org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:952)

       

      {code}

        • 1. Re: EJB with constructor injection not working in servlet
          tcesposito

          I was having a similar problem where I could not get an @EJB reference to a @Stateless session bean working from a @ManagedBean in a JSF page.  For the stateless session bean, I had a @Local and @Remote interface specified.  Because everything was running on the same AS7 instance, I made my @EJB reference to the local interface.  When I switched it to the remote interface it worked.  I'm not sure if this is the expected behavior, but it's working.

          • 2. Re: EJB with constructor injection not working in servlet
            arendvr.com

            Thanks for the tip.

             

            I made another test:

            • Introduced a new Interface GreeterInterface

            public interface GreeterInterface {

             

                String greet();

            }

            • Changed type of Field greeterEjb from GreeterEjb to GreeterInterface
            • GreeterEjb implements GreeterInterface

             

            Results:

            • @Remote annotation on GreeterInterface: Test still fails, but I get a different exception at deployment: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [GreeterInterface] with qualifiers [@Default] at injection point [[field] @Inject private com.example.ejbconstructorinjection.InjectedServlet.greeterEjb]"}}
            • @Local annotation on GreeterInterface: Now the test works fine
            • no annotation on GreeterInterface: Now the test works fine

             

            I still don't understand what the problem is. Also I don't understand how @Remote or @Local are supposed to change things in this case. The only thing I found was that CDI is not supposed to work with @Remote.

             

            And adding an otherwise useless interface is not really a pretty solution.