I have a JSF 2 #ViewScoped based webapp, that I cannot get the transactions to go with correctly, or rather: they don't start at all.
I'm using Java EE 6's CDI and EJB3, too.
Here's the main bean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
...
#ManagedBean
#ViewScoped
#Stateless
public class PqManager implements Serializable
{
private List<PqListItem> pqItems;
#Inject
private PqService pqService;
public List<PqListItem> getPqItems()
{
if ( pqItems == null )
{
pqItems = pqService.findActivePqs();
}
return pqItems;
}
...
}
The view-scoped bean is used from a JSF page to display a simple list in a datatable. It was made view-scoped because it has AJAX-based operations to add items, remove items, and to sort them via RichFaces (filtering).
I added #Stateless for every method invocation to start a transaction (or create a new one if none exists, the default is TransactionAttributeType.REQUIRED). This idea was taken from the book 'Core JavaServer Faces, 3rd ed.', however I haven't found any examples that would match my own.
Injected PqService class (it doesn't make a difference to use #EJB instead):
#Stateless
public class PqService extends JpaCrudService
{
...
public List<PqListItem> findActivePqs()
{
return em.createQuery("SELECT NEW ... whatever not interesting here... WHERE pq.workflow = '" + Workflow.ACTIVE + "' GROUP BY pq.id", PqListItem.class).getResultList();
}
...
}
JpaCrudService (basically taken from Adam Bien's example http://www.adam-bien.com/roller/abien/entry/generic_crud_service_aka_dao):
//#Stateless
//#Local(CrudService.class)
#TransactionAttribute(TransactionAttributeType.MANDATORY)
public abstract class JpaCrudService implements CrudService
{
#PersistenceContext(unitName = "PqGeneratorPu")
protected EntityManager em;
#Override
public <T> T create(T t)
{
em.persist(t);
em.flush();
em.refresh(t);
return t;
}
...
}
The only difference is that I subclass JpaCrudService because I don't like queries stored in/at the entities. So I omitted the #Local annotation (correct me if that's wrong). #Stateless isn't inherited AFAIK and I only inject the subclasses so I also commented that one out.
That said, the bean is then accessed from a JSF page:
<rich:dataTable value="#{pqManager.pqItems}"
var="pq">
<f:facet name="header">
<h:outputText value="Active" />
</f:facet>
...
However, when loading the page, I get an exception:
javax.ejb.EJBTransactionRequiredException: Transaction is required for invocation: org.jboss.invocation.InterceptorContext#7a6c1c92
at org.jboss.as.ejb3.tx.CMTTxInterceptor.mandatory(CMTTxInterceptor.java:255)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:184)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:165)
at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:173)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:72)
at de.company.webapp.service.PqService$$$view95.findActivePqsFor(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:264)
at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52)
at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137)
at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:260)
at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:111)
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105)
at de.company.webapp.service.PqService$Proxy$_$$_Weld$Proxy$.findActivePqs(PqService$Proxy$_$$_Weld$Proxy$.java)
at de.company.webapp.facade.PqManager.getPqItems(PqManager.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
.
.
.
It fails because the call pqService.findActivePqsFor() doesn't run in an existing transaction (TransactionAttributeType.MANDATORY, which is inherited AFAIK).
Note, that the page is displayed correctly without using transactions by deleting the TransactionAttributeType.MANDATORY on the JpaCrudService and using an extended entity manager, but this was just for testing purposes.
But why isn't this working? Why isn't the transaction started here? Is there anything with the JSF #ViewScoped bean? Incompatible?
How do you repair this?
PS: I'm using JBoss AS 7.1.1.
Of you're using CDI drop the JSF annotations. JSF annotations don't control EJBs the way CDI will. You're probably confusing the container with the annotations being used. You could also use MyFaces CODI for some extensions or look at recreating the ViewScope with CDI. There are a few examples online.
Related
I get the below error, when setting the scope for the managedBean as ViewScoped. Below is the exception Im getting when trying to invoke the page
javax.faces.FacesException: java.io.NotSerializableException: javax.faces.model.ListDataModel
at com.sun.faces.renderkit.ResponseStateManagerImpl.getViewState(ResponseStateManagerImpl.java:137)
at javax.faces.application.StateManager.getViewState(StateManager.java:555)
at com.sun.faces.context.PartialViewContextImpl.renderState(PartialViewContextImpl.java:416)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:300)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:981)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1756)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:390)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
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:594)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.NotSerializableException: javax.faces.model.ListDataModel
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
Sep 26, 2012 4:01:13 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException: CDATA tags may not nest
at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.startCDATA(HtmlResponseWriter.java:630)
at javax.faces.context.ResponseWriterWrapper.startCDATA(ResponseWriterWrapper.java:172)
at javax.faces.context.PartialResponseWriter.startError(PartialResponseWriter.java:342)
at org.primefaces.context.PrimePartialResponseWriter.startError(PrimePartialResponseWriter.java:210)
at com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError(AjaxExceptionHandlerImpl.java:200)
at com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:123)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
Any pointers or help on resolving the issue is much appericiated. Thanks in Advance.
java.io.NotSerializableException: javax.faces.model.ListDataModel
Your view scoped bean has apparently a ListDataModel property. This is indeed not serializable as its state is per definition dependent on the current HTTP request (which is usually not to be saved/shared anywhere --which would in turn require serialization).
A view scoped bean spans across multiple HTTP requests and is by an unique key stored the HTTP session. Some but not all servletcontainers stores sessions on harddisk instead of on memory and this requires all Java objects which are (in)directly stored in the session to implement Serializable, including view scoped beans and all of its properties.
You can fix this particular issue in 2 ways:
Mark the property transient, get hold of the wrapped list as another property, and use lazy loading in the getter.
private transient DataModel<Foo> model;
private List<Foo> list;
public DataModel<Foo> getModel() {
if (model == null) {
model = new ListDataModel<Foo>(list);
}
return model;
}
Don't use DataModel, but use an alternative instead. A common requirement for having DataModel was in JSF 1.x being able to obtain the current row. But since EL 2.2, you could just pass that as method argument. See also How can I pass selected row to commandLink inside dataTable?
Two days ago I wrote this question:
How can I retrieve an object on #WindowScoped?
and BalusC answered with some suggestions, now I have some problem to understand if my problem is that the object in WindowScoped is stored properly or my code to retrieve it is wrong!
Well, as I said, I have an object that I stored in #WindowScoped annotation but I can retrive this object only the first time! Why?
I just have a doubt: the CODI extension of MyFaces could be configured in some manner? Or I can use it simple adding the jar files to my project?
However, these are parts of my code because I don't know where is the problem:
LogicBean.java (the object that I should retrive):
#ManagedBean (name="logicBean" )
#WindowScoped
public class LogicBean implements Serializable
{
String pageIncluded;
// getter and setter methods
public String action(String value)
{
setPageIncluded(value);
return "include";
}
}
include.xhtml:
<ui:include src="#{logicBean.pageIncluded}"/>
ProgettiController.java
#ManagedBean(name = "progettiController")
#SessionScoped
public class ProgettiController implements Serializable {
private FacesContext context = FacesContext.getCurrentInstance();
private LogicBean logicBean = context.getApplication().evaluateExpressionGet(context, "#{logicBean}", LogicBean.class);
//getter and setter methods
public void testMethod()
{
logicBean.action("WEB-INF/jsf/page1.xhtml");
}
}
I tried also using #ManagedProperty("#{logicBean}") and setting the scope as WindowScoped but nothing change...
EDIT: after some new trials I found a strange problem, on my include.xhtml I added #{progettiController.logicBean.getPageIncluded()} and #{logicBean.getPageIncluded()} for check these two fields o?
Well, when I load the application for the first time the variables are correctly set and I see what I want, the second time the first variable is setted with the new value but the second is empty and I don't see anything, but now is coming the strange thing... if I should try again the app I should open index.xhtml where I had some forms like this:
<h:form>
<h:commandLink action="#{logicBean.action('/WEB-INF/jsf/progetti/List.xhtml')}" value="Show All Progetti Items"/>
</h:form>
and which is the result?
The first variable remains set with the old value (wrong) but the second is setted correctly so I can review the page like I would!
If someone can help me I will thank him/her forever!
CODI is an extension to CDI, so you should manage your beans by CDI #Named annotation instead of the JSF #ManagedBean annotation. Then you can inject the other bean by CDI #Inject annotation. The following example should work:
import javax.inject.Named;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowScoped;
#Named
#WindowScoped
public class LogicBean implements Serializable {
// ...
}
and
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
#Named
#SessionScoped
public class ProgettiController implements Serializable {
#Inject
private LogicBean logicBean;
// ...
}
I get an NotSerializableException when shutting down Glassfish (3.1), due to an HtmlSelectOneMenu. I use HtmlSelectOneMenu in other controller beans, but they are not bound to the backing bean as this one. This happens only if there are sessions active on the server of course.
How can I avoid exception when starting/stopping Glassfish for the bounded JSF component ?
Controller Class
#ManagedBean
#SessionScoped
...
public class ActivityController implements Serializable {
..
private DataModel<MyObjcet> items = null;
private HtmlSelectOneMenu myMenu;
...
Exception
INFO: PWC2785: Cannot serialize session attribute activityController for session a4591e053e65effc743dade67eef
java.io.NotSerializableException: javax.faces.component.html.HtmlSelectOneMenu
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at org.apache.catalina.session.StandardSession.writeObject(StandardSession.java:2067)
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 java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at org.apache.catalina.session.StandardManager.writeSessions(StandardManager.java:699)
at org.apache.catalina.session.StandardManager.doUnloadToFile(StandardManager.java:618)
at org.apache.catalina.session.StandardManager.unload(StandardManager.java:589)
at org.apache.catalina.session.StandardManager.stop(StandardManager.java:879)
at org.apache.catalina.core.StandardContext.stop(StandardContext.java:5509)
at com.sun.enterprise.web.WebModule.stop(WebModule.java:529)
at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:1049)
at com.sun.enterprise.web.WebContainer.unloadWebModule(WebContainer.java:2191)
at com.sun.enterprise.web.WebContainer.unloadWebModule(WebContainer.java:2146)
at com.sun.enterprise.web.WebApplication.stop(WebApplication.java:151)
at org.glassfish.internal.data.EngineRef.stop(EngineRef.java:169)
at org.glassfish.internal.data.ModuleInfo.stop(ModuleInfo.java:302)
at org.glassfish.internal.data.ApplicationInfo.stop(ApplicationInfo.java:314)
at com.sun.enterprise.v3.server.ApplicationLifecycle.unload(ApplicationLifecycle.java:997)
at com.sun.enterprise.v3.server.ApplicationLifecycle.disable(ApplicationLifecycle.java:1952)
at com.sun.enterprise.v3.server.ApplicationLoaderService.stopApplication(ApplicationLoaderService.java:443)
at com.sun.enterprise.v3.server.ApplicationLoaderService.preDestroy(ApplicationLoaderService.java:411)
at com.sun.hk2.component.AbstractCreatorInhabitantImpl.dispose(AbstractCreatorInhabitantImpl.java:83)
at com.sun.hk2.component.SingletonInhabitant.release(SingletonInhabitant.java:81)
at com.sun.hk2.component.EventPublishingInhabitant.release(EventPublishingInhabitant.java:108)
at com.sun.hk2.component.LazyInhabitant.release(LazyInhabitant.java:133)
at com.sun.enterprise.v3.server.AppServerStartup.stop(AppServerStartup.java:415)
at com.sun.enterprise.glassfish.bootstrap.GlassFishImpl.stop(GlassFishImpl.java:88)
at com.sun.enterprise.v3.admin.StopServer.doExecute(StopServer.java:70)
at com.sun.enterprise.v3.admin.StopDomainCommand.execute(StopDomainCommand.java:95)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.run(CommandRunnerImpl.java:383)
Make it transient.
private transient HtmlSelectOneMenu myMenu;
This way the field will be skipped on (de)serialization. By the way, the DataModel is also not serializable.
On the other hand, binding components directly to the backing bean is in most cases a smell. You should consider looking (or asking) for an alternative approach which does not require binding components to the bean.
On a glassfish 3.1 server, I have a #Stateful session bean which is injected into another stateful session bean.
The stateful session bean which is injected presents my entity access layer, it itself has it's EntityManager injected with #PersistenceContext and it looks like this.
#Stateful
MyEAO {
#PersistenceContext
EntityManager em;
MyEAO() {
// default constructor
}
....
}
This access layer is injected into another stateful bean:
#Stateful
public class ShopAdmin implements ShopAdminInterface {
#EJB MyEAO;
....
}
This worked! - BUT NOW as soon as I added another constructor to MyEAO, injecting MyEAO into the 2nd bean fails with an exception.
The strange thing is, that both beans used to be #Stateless session beans in the past and there were no problems at all.
BTW, I used the second constructor to pass the entity manager for my JUnit tests which run outside of the glassfish container.
Short: In the "stateless era" everything worked as expected!
I'm quite new to EJB - so what am I missing here ?
Here is the stack trace:
com.sun.faces.mgbean.ManagedBeanCreationException: Bei der Ressourcen-Einspeisung auf dem verwalteten Bean securityGuardBean ist ein Fehler aufgetreten.
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:409)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:99)
at com.sun.el.parser.AstValue.getTarget(AstValue.java:127)
at com.sun.el.parser.AstValue.invoke(AstValue.java:217)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at com.sun.faces.facelets.tag.jsf.core.DeclarativeSystemEventListener.processEvent(EventHandler.java:128)
at javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.processEvent(UIComponent.java:2508)
at javax.faces.event.SystemEvent.processListener(SystemEvent.java:106)
at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2129)
at com.sun.faces.application.ApplicationImpl.invokeComponentListenersFor(ApplicationImpl.java:2077)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:286)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:244)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:108)
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:594)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:232)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:680)
Caused by: com.sun.faces.spi.InjectionProviderException: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Local ejb-ref name=de.sdata.service.SecurityGuardBean/sgi,Local 3.x interface =de.sdata.service.SecurityGuardInterface resolved to intra-app EJB SecurityGuard in module sdataEJB.jar,ejb-link=sdataEJB.jar#SecurityGuard,lookup=,mappedName=,jndi-name=,refType=Session into class de.sdata.service.SecurityGuardBean: Lookup failed for 'java:comp/env/de.sdata.service.SecurityGuardBean/sgi' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}
at org.glassfish.faces.integration.GlassFishInjectionProvider.inject(GlassFishInjectionProvider.java:194)
at com.sun.faces.mgbean.BeanBuilder.injectResources(BeanBuilder.java:205)
... 48 more
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Local ejb-ref name=de.sdata.service.SecurityGuardBean/sgi,Local 3.x interface =de.sdata.service.SecurityGuardInterface resolved to intra-app EJB SecurityGuard in module sdataEJB.jar,ejb-link=sdataEJB.jar#SecurityGuard,lookup=,mappedName=,jndi-name=,refType=Session into class de.sdata.service.SecurityGuardBean: Lookup failed for 'java:comp/env/de.sdata.service.SecurityGuardBean/sgi' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:703)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:470)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:171)
at org.glassfish.faces.integration.GlassFishInjectionProvider.inject(GlassFishInjectionProvider.java:184)
... 49 more
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/de.sdata.service.SecurityGuardBean/sgi' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: No object bound for java:comp/env/de.sdata.service.SecurityGuardBean/sgi [Root exception is java.lang.reflect.UndeclaredThrowableException]]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:599)
... 52 more
Caused by: javax.naming.NameNotFoundException: No object bound for java:comp/env/de.sdata.service.SecurityGuardBean/sgi [Root exception is java.lang.reflect.UndeclaredThrowableException]
at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:242)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:498)
... 56 more
Caused by: java.lang.reflect.UndeclaredThrowableException
at $Proxy273.create(Unknown Source)
at com.sun.ejb.EJBUtils.resolveEjbRefObject(EJBUtils.java:366)
at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:190)
at com.sun.enterprise.container.common.impl.ComponentEnvManagerImpl$EjbReferenceProxy.create(ComponentEnvManagerImpl.java:1106)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:776)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:744)
at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:172)
... 57 more
Caused by: javax.ejb.CreateException: ERROR creating stateful SessionBean
at com.sun.ejb.containers.StatefulSessionContainer.createEJBLocalBusinessObjectImpl(StatefulSessionContainer.java:551)
at com.sun.ejb.containers.BaseContainer.createEJBLocalBusinessObjectImpl(BaseContainer.java:2486)
at com.sun.ejb.containers.EJBLocalHomeImpl.createEJBLocalBusinessObjectImpl(EJBLocalHomeImpl.java:117)
at com.sun.ejb.containers.EJBLocalHomeInvocationHandler.invoke(EJBLocalHomeInvocationHandler.java:177)
... 64 more
Caused by: java.lang.InstantiationException: de.sdata.service._SecurityGuard_Serializable
at java.lang.Class.newInstance0(Class.java:340)
at java.lang.Class.newInstance(Class.java:308)
at com.sun.ejb.containers.StatefulSessionContainer._constructEJBInstance(StatefulSessionContainer.java:566)
at com.sun.ejb.containers.BaseContainer.createEjbInstanceAndContext(BaseContainer.java:1643)
at com.sun.ejb.containers.StatefulSessionContainer.createBeanInstance(StatefulSessionContainer.java:578)
at com.sun.ejb.containers.StatefulSessionContainer.createEJBLocalBusinessObjectImpl(StatefulSessionContainer.java:532)
... 67 more
I suspect that you don't have an explicit no-arg constructor in your class.
IMO it is not a good solution to add special constructor to the bean class because you need to
set some field for the tests. There are some nice tools that can do a lot of tricks for you.
Take a look at http://unitils.org/cookbook.html -->Test a JPA DAO which should be what you need.
Best,
A
From just a few searches, this seems like a problem that has been around for a while. I have written a FacesConverter that looks like the following. The object Category is a JPA entity and CategoryControl is the DAO that fetches it.
#FacesConverter(value = "categoryConverter")
public class CategoryConverter implements Converter {
#Inject private CategoryControl cc;
public CategoryConverter() { }
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (cc != null) return cc.getByName(value);
System.out.println("CategoryConverter().getAsObject(): no injection!");
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (!(value instanceof Category)) return null;
return ((Category) value).getName();
}
}
As you probably guessed by now, I never get the injection. I got this workaround from this page, which looks like this.:
Workaround for this problem: create this method in your localeController:
public Converter getConverter()
{
return FacesContext.getCurrentInstance().getApplication().createConverter("localeConverter");
}
and use converter="#{localeController.converter}" in your h:selectOneMenu.
However I can't make this work either. My backing bean creates and returns a converter all right, but it doesn't get the object injected into it.
I am using MyFaces CODI 1.0.1. With the current GlassFish/Weld container. Can anyone suggest a solution before I re-code to not use a Converter?
Replace
#FacesConverter(value = "categoryConverter")
by
#Named
and use
<h:inputSomething converter="#{categoryConverter}" />
or
<f:converter binding="#{categoryConverter}" />
instead of
<h:inputSomething converter="categoryConverter" />
or
<f:converter converterId="categoryConverter" />
By the way, similar problem exist for #EJB inside a #FacesConverter. It however offers a way to be grabbed by JNDI manually. See also Communication in JSF 2.0 - Getting an EJB in #FacesConverter and #FacesValidator. This way you can use a #FacesConverter(forClass=Category.class) without manually defining it everytime. Unfortunately I can't tell from top of head how to realize that for CDI beans.
Update: if you happen to use JSF utility library OmniFaces, since version 1.6 is adds transparent support for using #Inject and #EJB in a #FacesConverter class without any additional configuration or annotations. See also the CDI #FacesConverter showcase example.
The #Inject Annotation only works in CDI managed instances. If you want to use CDI features inside a non-CDI managed instance (Like a JSF Validator or a JSF Converter) you can just programm against the CDI API.
This works only in at least Java EE 7 + CDI 1.1 server.
#FacesValidator("userNameValidator")
public class UserNameValidator implements Validator {
private UserService userService;
public UserNameValidator(){
this.userService = CDI.current().select(UserService.class).get();
}
#Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
....
}
}
https://docs.oracle.com/javaee/7/api/javax/enterprise/inject/spi/CDI.html
With all the AnnotationHell in Java EE people forget how to code.
Just use #Advanced of CODI for your #FacesConverter see the Wiki.
As soon as a converter or a validator is annotated with #Advanced it's possible to use #Inject.
Per BalusC's answer here, I decided to add JSF (requestscoped) managed beans that only contained #FacesConverter and Converter to resolve this issue in my app, since I'm migrating from JSF managed beans to CDI managed beans.
I tried CODI #Advanced against #FacesConverter, but it does not inject the bean at all.