6 Replies Latest reply on Jan 16, 2010 3:52 PM by meetoblivion

    EJB Injection

    meetoblivion

      We're using an abstract DAO class, along with an interface for it:


      public abstract class AbstractDAO<E> {
          @PersistenctContext EntityManager em;
          public boolean save(E entity) {
              em.merge(entity);
              return true;
          }
      }
      
      public interface AbstractDAOBean<E> {
          public boolean save(E entity);
      }





      I also created an implementation:




      @Local
      public interface ResultDAOBean extends AbstractDAOBean<Result> {
          public Result findByUser(String username);
      }
      
      @DAO
      @Local(ResultDAOBean.class)
      @Stateless
      public ResultDAO extends AbstractDAO<Result> implements ResultDAOBean{
          public Result findByUser(String username) { .... }
      }




      Now, @DAO is a qualifier.  I want to use this EJB in my classes, and I think I should be able to.  So I add the following injection point to my code.


      @Inject @DAO ResultDAOBean resultDAOBean;


      No matter what combination I try, the exception reads along these lines:




      Caused by: java.lang.IllegalStateException: Unable to convert ejbRef for ejb ResultDAO to a business object of type interface AbstractDAOBean
              at com.sun.ejb.containers.EjbContainerServicesImpl.getBusinessObject(EjbContainerServicesImpl.java:104)
              at org.glassfish.weld.ejb.SessionObjectReferenceImpl.getBusinessObject(SessionObjectReferenceImpl.java:60)
              at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:121)
              at jpa.dao.EvaluationDAOBean_$$_javassist_110.getEM(EvaluationDAOBean_$$_javassist_110.java)
              at NewSessionBean.init(NewSessionBean.java:30)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at com.sun.ejb.containers.interceptors.BeanCallbackInterceptor.intercept(InterceptorManager.java:1006)
              at com.sun.ejb.containers.interceptors.CallbackChainImpl.invokeNext(CallbackChainImpl.java:61)
              at com.sun.ejb.containers.interceptors.CallbackInvocationContext.proceed(CallbackInvocationContext.java:109)
              at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCallback(SystemInterceptorProxy.java:133)
              at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.init(SystemInterceptorProxy.java:115)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at com.sun.ejb.containers.interceptors.CallbackInterceptor.intercept(InterceptorManager.java:961)
              at com.sun.ejb.containers.interceptors.CallbackChainImpl.invokeNext(CallbackChainImpl.java:61)
              at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:390)
              at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:373)
              at com.sun.ejb.containers.AbstractSingletonContainer.createSingletonEJB(AbstractSingletonContainer.java:518)
              ... 38 more



      So it looks like no matter what, Weld is trying to find the lowest interface rather than the local bean.

        • 1. Re: EJB Injection
          gavin.king

          Well, for a start, you don't need this annotation:

          @Local(ResultDAOBean.class)

          • 2. Re: EJB Injection
            meetoblivion

            Gavin King wrote on Jan 14, 2010 06:25:


            Well, for a start, you don't need this annotation:
            @Local(ResultDAOBean.class)




            Right....  I know it's not required, but it's also not illegal to have it there.  So weld should still be able to process the class just fine.


            I did try a few more iterations.  The obvious one being, convert it to a @LocalBean and do some copy and paste inheritence worked fine (no extends or implements).  This was kind of a given.  Removing both interfaces also does not work, then it seems like Weld is trying to proxy for the abstract class, not the implementation.  I think that issue's been shown before on the forums though.  The version that did end up working was dropping the AbstractDAOBean from the equation - define all of the business interface methods in ResultDAOBean works in a proper deployment.


            I'm not sure if this is a bug that's been shown before or not.

            • 3. Re: EJB Injection
              nickarls

              File a JIRA just in case and let Pete sort it out ;-)

              • 4. Re: EJB Injection
                asookazian

                So is this a current limitation of Weld in that you can't use an abstract class because Weld proxies the abstract class rather than the interface or impl class?


                Or is this a OOP pattern that is not recommended or supported in EE 6?


                What if you extend the abstract class but not implement any interface?  Still a problem?

                • 5. Re: EJB Injection
                  meetoblivion

                  Arbi Sookazian wrote on Jan 14, 2010 17:47:


                  What if you extend the abstract class but not implement any interface?  Still a problem?


                  This also fails.  It tries to fill in my implementation into a proxied abstract.  JIRA's on its way.

                  • 6. Re: EJB Injection
                    meetoblivion

                    Ok, JIRA's finally back up WELD-381