I'm getting exception "javax.ejb.NoSuchEJBException: JBAS016055: EJB has been removed" when using JBoss 7.1.3 with Weld 1.1.9 or Weld 1.1.10 in web app. It happens after there is some runtime exception in one of my stateful ejb beans. Until user will create new session (for example by closing web browser and opening it once again) he cannot use application at all because each request ends with "javax.ejb.NoSuchEJBException: JBAS016055: EJB has been removed". What's strange is that exceptions seems to be caused by logging code in Weld. Below is how to replicate my problem and exception that I'm constantly getting. Is it know problem? Is there a workaround other than "don't throw exceptions in stateful beans"?

btw. I think it would be better if logging statements in Weld wouldn't use string concatenation because currently no matter what logging level is selected message is always constructed which might be bad for performance reasons

When a stateful bean throws a system exception, the bean is always removed. So all subsequent calls to the bean's methods will then throw a NoSuchEJBException. This is perfectly ok if it happens when client code is invoking the methods. Of course it's not ok that weld is the one invoking these methods for every request and not handling the exception appropriately. We'll need to see what we can do about this.

Can you try my branch? I'm interested in seeing if there are any other places where Weld invokes methods of the EJB.

Marko, thank you very much for investigating this issue. I wasn't able to directly use your branch because it's based on Weld 1.1.5 or 1.1.6 which isn't compatibile with jboss as <-> Weld integration present in JBoss 7.1.3. Anyway, I took sources of Weld 1.1.10 and applied there your changes and exception is gone for ExceptionGenerator class that I put in my first post. Still, it will fail if ExceptionGenerator class has some extra field which is then used on facelets page. To make things easier I've put my exception tester app on https://github.com/pczekaj/exception-tester

I checked my sample app on JBoss 7.1.1 and it works better, there is no 'javax.ejb.NoSuchEJBException: JBAS016055: EJB has been removed'. But I'm not sure if it works correctly. When I load a page for the first time (or after session has expired) I can see sth similiar to:

exceptionGenerator created at: Fri Oct 26 11:05:43 CEST 2012

Current time: Fri Oct 26 11:05:43 CEST 2012

After causing exception in ExceptionGenerator class and opening page once again I can see:

exceptionGenerator created at:

Current time: Fri Oct 26 11:06:59 CEST 2012

so it looks like that new instance ExceptionGenerator class wasn't created and Weld is trying to access one which has been removed, in JBoss 7.1.1 it doesn't throw exception here. I don't know how CDI standard defines how should it behave in such situation but for me it should create new instance of ExceptionGenerator.

In JBoss 7.1.3 and Weld 1.1.10 patched the same way as Marko's version (log.isTraceEnabled()) it behaves differently, after causing exception in ExceptionGenerator each new request to open page when that bean is used causes:

11:18:59,568 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-localhost/127.0.0.1:8080-2) Error Rendering View[/index.xhtml]: javax.el.ELException: /index.xhtml @13,94 value="exceptionGenerator created at: #{exceptionGenerator.constructedAt}": javax.ejb.NoSuchEJBException: JBAS016055: EJB has been removed
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114) [jsf-impl-2.1.11-jbossorg-3.jar:]
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at javax.faces.component.UIOutput.getValue(UIOutput.java:169) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205) [jsf-impl-2.1.11-jbossorg-3.jar:]
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355) [jsf-impl-2.1.11-jbossorg-3.jar:]
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164) [jsf-impl-2.1.11-jbossorg-3.jar:]
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1786) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:424) [jsf-impl-2.1.11-jbossorg-3.jar:]
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125) [jsf-impl-2.1.11-jbossorg-3.jar:]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121) [jsf-impl-2.1.11-jbossorg-3.jar:]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.11-jbossorg-3.jar:]
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [jsf-impl-2.1.11-jbossorg-3.jar:]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.17.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.17.Final.jar:]
at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.10.Final.jar:2012-10-26 09:53]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.17.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.17.Final.jar:]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.17.Final.jar:]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.17.Final.jar:]
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.3.Final.jar:7.1.3.Final]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:165) [jboss-as-web-7.1.3.Final.jar:7.1.3.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.17.Final.jar:]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.17.Final.jar:]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.17.Final.jar:]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:372) [jbossweb-7.0.17.Final.jar:]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.17.Final.jar:]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:679) [jbossweb-7.0.17.Final.jar:]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:931) [jbossweb-7.0.17.Final.jar:]
at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_35]
Caused by: javax.ejb.NoSuchEJBException: JBAS016055: EJB has been removed
at org.jboss.as.weld.ejb.StatefulSessionObjectReferenceImpl.getBusinessObject(StatefulSessionObjectReferenceImpl.java:124) [jboss-as-weld-7.1.3.Final.jar:7.1.3.Final]
at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:109) [weld-core-1.1.10.Final.jar:2012-10-26 09:53]
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56) [weld-core-1.1.10.Final.jar:2012-10-26 09:53]
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105) [weld-core-1.1.10.Final.jar:2012-10-26 09:53]
at org.jboss.tools.examples.controller.ExceptionGenerator$Proxy$_$$_Weld$Proxy$.getConstructedAt(ExceptionGenerator$Proxy$_$$_Weld$Proxy$.java) [classes:]
at org.jboss.tools.examples.controller.ExceptionGenerator$Proxy$_$$_WeldClientProxy.getConstructedAt(ExceptionGenerator$Proxy$_$$_WeldClientProxy.java) [classes:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.6.0_35]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [rt.jar:1.6.0_35]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [rt.jar:1.6.0_35]
at java.lang.reflect.Method.invoke(Method.java:597) [rt.jar:1.6.0_35]
at javax.el.BeanELResolver.getValue(BeanELResolver.java:302) [jboss-el-api_2.2_spec-1.0.2.Final.jar:1.0.2.Final]
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176) [jsf-impl-2.1.11-jbossorg-3.jar:]
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203) [jsf-impl-2.1.11-jbossorg-3.jar:]
at org.apache.el.parser.AstValue.getValue(AstValue.java:169) [jbossweb-7.0.17.Final.jar:]
at org.apache.el.parser.AstDeferredExpression.getValue(AstDeferredExpression.java:44) [jbossweb-7.0.17.Final.jar:]
at org.apache.el.parser.AstCompositeExpression.getValue(AstCompositeExpression.java:50) [jbossweb-7.0.17.Final.jar:]
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189) [jbossweb-7.0.17.Final.jar:]
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50) [weld-core-1.1.10.Final.jar:2012-10-26 09:53]
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109) [jsf-impl-2.1.11-jbossorg-3.jar:]
... 37 more

Maybe it would be worthwhile to look at org.jboss.as.weld.ejb.StatefulSessionObjectReferenceImpl, one of recent commits (29/04/2012) to it states:

I don't know how CDI standard defines how should it behave in such situation but for me it should create new instance of ExceptionGenerator.

I couldn't find any statement in the CDI spec supporting that it should do that. IMHO it would not be a good idea, as it could put the application into an unexpected state, as some SFSB would silently reset into their initial state in the middle of some kind of a workflow. (It would make sense only if it invalidated the whole session)

I don't think either that CDI should go and get a new SFSB instance in that case. This needs clarification, though. In CDI 1.1 we introduced the contept of AlterableContext where you can relese resources by destroying an existing normal-scoped instance. A new one will be recreated on demand again.

That means that after getting the exception your code would be responsible for calling SessionContext.destroy(instance). Afterwards, it would get a new instance of the SFSB. This is explicit and does not lead to surprises where your code suddently works with a different instance.

I can confirm that snapshot of weld 1.11 running on JBoss 7.1.3 doesn't have a problem described in my first post in this thread. Thank you very much for fixing it.

Invalidating whole session would be nice feature, probably better than creating new instance of removed bean because of runtime excepion and that's what I usually do when programming in dot net. I've wrote about creating new instance in such situation because if I'm correct currently it also puts application is strange state: maybe facelet page will render but some parts might be missing, for example normally page contains:

That facelets page wouldn't even render if it would try to access something that cannot be null (like int). What's more if I would inject somewhere class that has been removed because of exception then that new bean would stop working because of NullPointerException. Had one bean not working, now have 2 of them and it can continue that way...

What's the best practice in CDI to handle such unexpected runtime exceptions?