Is it possible to have @EJB as generic type?

import javax.ejb.EJB;

public abstract class AbstractController<TEJB extends EntityEJB<TENTITY>, TENTITY extends EntityInterface> {
    @EJB
    protected TEJB ejb;
    ...

import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;

@ManagedBean
@SessionScoped
public class UserController extends AbstractController<UserEJB, User> {
    ...

import javax.ejb.Stateless;

@Stateless
public abstract class EntityEJB<T extends EntityInterface> {
    ...

import javax.ejb.Stateless;

@Stateless
public class UserEJB extends EntityEJB<User> {
    ...

It compiles, deploys but whenever code goes into some EJB method, it throws:

    [#|2011-02-14T12:36:20.531+0100|WARNING|glassfish3.0.1|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=25;_ThreadName=Thread-1;|A system exception occurred during an invocation on EJB EntityEJB method public int ejb.EntityEJB.getItemCount()
javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
    at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:448)
    at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2467)
    at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1860)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:188)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:84)
    at $Proxy150.getItemCount(Unknown Source)
    at ejb.__EJB31_Generated__EntityEJB__Intf____Bean__.getItemCount(Unknown Source)
    at controller.AbstractController.getItemCount(AbstractController.java:88)
    at controller.AbstractController.getPagingInfo(AbstractController.java:29)
    at controller.AbstractController.getItems(AbstractController.java:40)
    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 javax.el.BeanELResolver.getValue(BeanELResolver.java:302)
    at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175)
    at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:116)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:163)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:102)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:178)
    at javax.faces.component.UIData.getValue(UIData.java:554)
    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.faces.facelets.util.DevTools.writeAttributes(DevTools.java:368)
    at com.sun.faces.facelets.util.DevTools.writeStart(DevTools.java:417)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:238)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:257)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:257)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:257)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:257)
    at com.sun.faces.facelets.util.DevTools.writeComponent(DevTools.java:257)
    at com.sun.faces.facelets.util.DevTools.debugHtml(DevTools.java:121)
    at com.sun.faces.renderkit.RenderKitUtils.renderHtmlErrorPage(RenderKitUtils.java:1139)
    at com.sun.faces.context.ExceptionHandlerImpl.throwIt(ExceptionHandlerImpl.java:249)
    at com.sun.faces.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:136)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
    at java.lang.Thread.run(Thread.java:619)
Caused by: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
    at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:720)
    at com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:200)
    at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:443)
    ... 66 more
Caused by: javax.ejb.CreateException: Could not create stateless EJB
    at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:528)
    at com.sun.ejb.containers.StatelessSessionContainer.access$000(StatelessSessionContainer.java:90)
    at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:718)
    ... 68 more
Caused by: java.lang.InstantiationException
    at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:30)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at java.lang.Class.newInstance0(Class.java:355)
    at java.lang.Class.newInstance(Class.java:308)
    at com.sun.ejb.containers.BaseContainer._constructEJBInstance(BaseContainer.java:1640)
    at com.sun.ejb.containers.BaseContainer.createEjbInstanceAndContext(BaseContainer.java:1623)
    at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:469)
    ... 70 more

If I change EJB from generic type to concrete class (UserEJB), it works well. I’m sorry if this is beginner question, I’m just starting with Java …

Bozho noted that abstract class should not be annotated with @Stateless. This makes sense but then it seems to crash even earlier – because it cannot find EJB named “EntityEJB”. Ok, it seems that in former case dependency injector tries to inject instance of EntityEJB (this is superclass of generics TEJB) which is abstract class which cannot be instantiated (and therefore not injected) and this causes exception “Could not create stateless EJB”. Whole stacktrace wihtout @Stateless:

com.sun.faces.mgbean.ManagedBeanCreationException: An error occurred performing resource injection on managed bean groupController
    at com.sun.faces.mgbean.BeanBuilder.injectResources(BeanBuilder.java:211)
    at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:103)
    at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:405)
    at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:267)
    at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:86)
    at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175)
    at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
    at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:99)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:158)
    at com.sun.el.parser.AstPlus.getValue(AstPlus.java:55)
    at com.sun.el.parser.AstDeferredExpression.getValue(AstDeferredExpression.java:59)
    at com.sun.el.parser.AstCompositeExpression.getValue(AstCompositeExpression.java:64)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:102)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:178)
    at javax.faces.component.UIOutput.getValue(UIOutput.java:168)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:338)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:878)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1620)
    at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:287)
    at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:106)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:287)
    at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185)
    at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:380)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
    at java.lang.Thread.run(Thread.java:619)
Caused by: com.sun.faces.spi.InjectionProviderException: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=controller.AbstractController/ejb,Remote 3.x interface =ejb.EntityEJB,ejb-link=null,lookup=null,mappedName=,jndi-name=ejb.EntityEJB,refType=Session into class controller.AbstractController
    at org.glassfish.faces.integration.GlassFishInjectionProvider.inject(GlassFishInjectionProvider.java:98)
    at com.sun.faces.mgbean.BeanBuilder.injectResources(BeanBuilder.java:205)
    ... 63 more
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=controller.AbstractController/ejb,Remote 3.x interface =ejb.EntityEJB,ejb-link=null,lookup=null,mappedName=,jndi-name=ejb.EntityEJB,refType=Session into class controller.AbstractController
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:614)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:384)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:168)
    at org.glassfish.faces.integration.GlassFishInjectionProvider.inject(GlassFishInjectionProvider.java:94)
    ... 64 more
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/controller.AbstractController/ejb' in SerialContext  [Root exception is javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=controller.AbstractController/ejb,Remote 3.x interface =ejb.EntityEJB,ejb-link=null,lookup=null,mappedName=,jndi-name=ejb.EntityEJB,refType=Session' .  Actual (possibly internal) Remote JNDI name used for lookup is 'ejb.EntityEJB#ejb.EntityEJB' [Root exception is javax.naming.NamingException: Lookup failed for 'ejb.EntityEJB#ejb.EntityEJB' in SerialContext  [Root exception is javax.naming.NameNotFoundException: ejb.EntityEJB#ejb.EntityEJB not found]]]
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:442)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:513)
    ... 67 more
Caused by: javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=controller.AbstractController/ejb,Remote 3.x interface =ejb.EntityEJB,ejb-link=null,lookup=null,mappedName=,jndi-name=ejb.EntityEJB,refType=Session' .  Actual (possibly internal) Remote JNDI name used for lookup is 'ejb.EntityEJB#ejb.EntityEJB' [Root exception is javax.naming.NamingException: Lookup failed for 'ejb.EntityEJB#ejb.EntityEJB' in SerialContext  [Root exception is javax.naming.NameNotFoundException: ejb.EntityEJB#ejb.EntityEJB not found]]
    at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:174)
    at com.sun.enterprise.container.common.impl.ComponentEnvManagerImpl$EjbReferenceProxy.create(ComponentEnvManagerImpl.java:1040)
    at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:688)
    at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:657)
    at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:148)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:428)
    ... 69 more
Caused by: javax.naming.NamingException: Lookup failed for 'ejb.EntityEJB#ejb.EntityEJB' in SerialContext  [Root exception is javax.naming.NameNotFoundException: ejb.EntityEJB#ejb.EntityEJB not found]
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:442)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:169)
    ... 74 more
Caused by: javax.naming.NameNotFoundException: ejb.EntityEJB#ejb.EntityEJB not found
    at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:197)
    at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:168)
    at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:58)
    at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:101)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:430)
    ... 76 more

Answer

@EJB is a annotation used to inject it in your class. You cannot annotated it with a genneric class or your Container will not be able to find what instance should be used in this field.

Leave a Reply

Your email address will not be published. Required fields are marked *