Page On load event in JSF - jsf

I am trying to assign values to my dropdown during page load. I followed the way which is given in this link.
Invoke JSF managed bean action on page load
As per the link, i have tried using both the annotation and constructor type.
but its an exception for me,
SEVERE: An exception occurred
javax.faces.FacesException: java.lang.reflect.InvocationTargetException
Caused by: java.lang.reflect.InvocationTargetException
Caused by: javax.el.ELException: Detected cyclic reference to managedBean loginBean
Caused by: javax.faces.el.EvaluationException: Detected cyclic reference to managedBean loginBean
I have just tried to call a function, in that annotated method or constructor,
that is,
#PostConstruct
public void init()
{
receiveclass r=new receiveclass();
r.retrieve();
}
i cant able to figure out the problem.

Detected cyclic reference to managedBean loginBean
You're injecting two different managed beans in each other as #ManagedProperty. This isn't allowed. It should be an one-way injection. Remove the #ManagedProperty referencing the one bean from the other bean.

Related

Bean class cannot be loaded due to a missing dependency: LazyDataModel

I'm using the primefaces framework to realise a lazy data table.
I imported the package:
import org.primefaces.model.LazyDataModel;
in my EventViewer ManagedBean class.
I put the primefaces-6.1.jar in the WEB-INF/lib folder.
After deploying the project on JBoss AS, when loading the page I get the following exception:
2017-07-25 18:12:13,817 ERROR [javax.enterprise.resource.webcontainer.jsf.managedbean] JSF will be unable to create managed bean eventViewer when it is requested. The following problems where found:
- Bean or property class com.imnet.oam.fe.event.EventViewer for managed bean eventViewer cannot be loaded due to a missing dependency: org/primefaces/model/LazyDataModel.
2017-07-25 18:12:13,817 ERROR [javax.enterprise.resource.webcontainer.jsf.application] Error Rendering View[/event.xhtml]
com.sun.faces.mgbean.ManagedBeanCreationException: Unable to create managed bean eventViewer. The following problems were found:
- Bean or property class com.imnet.oam.fe.event.EventViewer for managed bean eventViewer cannot be loaded due to a missing dependency: org/primefaces/model/LazyDataModel.
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:265)
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 org.jboss.el.parser.AstIdentifier.getValue(AstIdentifier.java:44)
at org.jboss.el.parser.AstValue.getValue(AstValue.java:63)
at org.jboss.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIData.getValue(UIData.java:732)
at org.primefaces.component.api.UIData.getDataModel(UIData.java:764)
at org.primefaces.component.datatable.DataTable.loadLazyData(DataTable.java:1097)
[...]
This is the main error:
- Bean or property class com.imnet.oam.fe.event.EventViewer for managed bean eventViewer cannot be loaded due to a missing dependency: org/primefaces/model/LazyDataModel.
How do I solve it?

Managed Bean not being instantiated at #ApplicationScoped and eager=true

I have the following UserView class:
#ManagedBean(name="usersView", eager=true)
#ApplicationScoped
public class UserView
{
...
public void setUsers(...)
{
...
}
}
I then have another class, UserService which tries to access this bean and then call this method, as follows:
UserView usersView = (UserView) FacesContext.getCurrentInstance().getExternalContext().getSessionMap("usersView");
usersView.setUsers(...)
My issue is, is that usersView keeps coming back as null and hence the method cannot be called.
My end goal is to use this data in a PrimeFaces datatable, like so:
<p:dataTable var="user" value="#{usersView.users}" ...>
I have also tried changing the scope to SessionScoped, but it is still null and I cannot figure out why.
Any suggestions would be greatly appreciated.
The getExternalContext().getXxxMap().get("beanName") approach won't autocreate beans if they don't exist yet. Managed beans will only be autocreated when an EL expression referencing the bean is evaluated. Accessing the scope map doesn't do that. For that, use #ManagedProperty in the source bean instead. You can specify an EL expression in its value.
#ManagedProperty("#{userView}")
private UserView userView; // +setter (no getter required).
Note that this only works if the source bean has the same or a narrower scope than the target bean. If that's not the case, consider managing beans using CDI instead of JSF. You can then use #Inject instead of #ManagedProperty (which doesn't require a setter by the way). Moreover, #ManagedBean and friends is deprecated in upcoming JSF 2.3.
As to eager=true, this has only effect on #ApplicationScoped beans. See also the javadoc (emphasis mine).
...
If the value of the eager() attribute is true, and the managed-bean-scope value is "application", the runtime must instantiate this class when the application starts. This instantiation and storing of the instance must happen before any requests are serviced. If eager is unspecified or false, or the managed-bean-scope is something other than "application", the default "lazy" instantiation and scoped storage of the managed bean happens.
...
See also:
How to choose the right bean scope?
Difference between #ManagedProperty and FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("bean")
Get JSF managed bean by name in any Servlet related class
Backing beans (#ManagedBean) or CDI Beans (#Named)?

View scope: java.io.NotSerializableException: javax.faces.component.html.HtmlInputText

There is an error each time a button calls an action from the backing-bean.
Only applies to beans with a view scope and I haven't found a way to fix it without regression over other modules in the code.
DefaultFacele E Exiting serializeView - Could not serialize state: javax.faces.component.html.HtmlInputText
java.io.NotSerializableException: javax.faces.component.html.HtmlInputText
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
Or also:
com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception
root cause Faces Servlet: ServletException: /jspFiles/jsf/Deployments/editQueue.faces No saved view state could be found for the view identifier /jspFiles/jsf/Deployments/editQueue.faces
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:205)
Caused by: javax.faces.application.ViewExpiredException: /jspFiles/jsf/Deployments/editQueue.faces No saved view state could be found for the view identifier: /jspFiles/jsf/Deployments/editQueue.faces
at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute (RestoreViewExecutor.java:128)
faces-config.xml
<managed-bean>
<managed-bean-name>pc_EditQueue</managed-bean-name>
<managed-bean-class>pagecode.jspFiles.jsf.deployments.EditQueue</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
<managed-property>
<property-name>queueDeploymentBean</property-name>
<value>#{queueDeploymentBean}</value>
</managed-property>
</managed-bean>
web.xml
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
<param-value>true</param-value>
</context-param>
bean:
#ManagedBean
#ViewScoped
public class EditQueue extends PageCodeBase implements Serializable {
private static final long serialVersionUID = -1L;
public String doButtonAddAction() {
// calls manager (long)
FacesUtil.setViewMapValue("queueDeploymentBean", queueDeploymentBean);
return "";
}
I read this suggestion to set SERIALIZE_STATE_IN_SESSION to false and indeed this solution works for this view scope bean. However this fix comes at a high cost: many existing modules in the application don't work anymore so I cannot use this fix there. Some of the regression observed are:
// returns null must be changed with FacesUtil.getSessionMapValue("userId");
getSessionScope().get("userId");`
// returns null must be changed with FacesUtil.getViewMapValue("linkerBean");
linkerBean = (Linker) getManagedBean("linkerBean");`
// NPE so must be changed with FacesContext.getCurrentInstance().addMessage(...)
getFacesContext().addMessage(...)`
So my questions are:
why the NotSerializableException even though the bean implements Serializable ?
is there a way to apply the SERIALIZE_STATE_IN_SESSION param over only a subset of the beans or not ?
is there another solution to have my view scope bean to work (without having to change them to request scope or else) ?
WebSphere 8.0.0.3,
Java 1.6.0,
JSF 2.0,
RichFaces 4.2.3.Final
why the NotSerializableException even though the bean implements Serializable ?
Not only the bean needs to be serializable, but all of its properties (and all their nested properties etc) must also be serializable. The name of the offending non-serializable class can easily be found in the exception message:
java.io.NotSerializableException: javax.faces.component.html.HtmlInputText
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
This suggests that you're binding a <h:inputText> component to the bean like below:
<h:inputText binding="#{bean.fooInput}" ...>
private UIComponent fooInput;
This is indeed illegal when the bean is not in request scope. UIComponent instances are request scoped and may not be shared across multiple requests. Moreover, UIComponent instances are not serializable. Only their state is, but JSF will worry about that all by itself.
You must remove the fooInput property and you need to look for a different solution for the problem for which you incorrectly thought that binding the component to a view scoped bean would be the right solution.
If you intend to access it elsewhere in the view, e.g. #{bean.fooInput.value}, then just bind it to the Facelet scope without the need for a bean property:
<h:inputText binding="#{fooInput}" ...>
It'll be available elsewhere in the same view via #{fooInput.xxx}.
<h:inputText ... required="#{empty fooInput.value}" />
If you intend to set some component attribute programmatically inside the bean, e.g. fooInput.setStyleClass("someClass"), or fooInput.setDisabled(true), then you should be binding the specific attribute in the view instead of the whole component:
<h:inputText ... styleClass="#{bean.styleClass}" />
...
<h:inputText ... disabled="#{bean.disabled}" />
If you are absolutely positive that you need to get a hand of whole UIComponent instance in the bean for whatever reason, then manually grab it in method local scope instead of binding it:
public void someMethod() {
UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
UIComponent fooInput = view.findComponent("formId:fooInputId");
// ...
}
But better ask a question or search for an answer how to solve the concrete problem differently without the need to grab a whole component in the backing bean.
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?
As to the ViewExpiredException, this has different grounds which is further elaborated in javax.faces.application.ViewExpiredException: View could not be restored.

How to instantiate a backing bean on page load

For a project we are migrating some java applications to WebSphere 8.5. In the process we are trying to get rid of some legacy frameworks. One of them is shale (apache attic). The only component from shale that is used is the view controller to instantiate a request scoped jsf managed beans for every page. Every bean has an init method that is called on page load. I'd like to use #PostConstruct on this method. The only problem I have that the bean gets instantiated when a method on the bean is called. Unfortunately the bean is not always called and the init method does populate data on a session scoped bean. There is a naming convention that links pages and beans so we could use a listener to instantiate the bean based on the request. Another solution might be changing the scope to viewscope (probably to much a hassle on websphere 8.5).
I was wondering if there is something I can do to make the PostConstruct work? And are there other options I'm missing?
edit:
I have a PhaseListener in place that performs the basic functionality. It matches the requested page to the corresponding bean (by naming convention). The following is used to instantiate the bean but it looks a bit ugly.
expressionFactory.createValueExpression(elContext, "#{" + managedBeanName + "}", Object.class)
Is there a more elegant way to do this?
Perhaps you could try using <f:event/> ?
In your view, you could add this to the page.
<f:event type="postAddToView" listener="#{backingBean.myInitMethod()"/>
https://stackoverflow.com/a/14004230/4706826
Gives you info on when the events get executed.
Put a #PostConstruct annotated method in the backing bean. This annotation tells the bean to execute the annotated method every time its constructor is being called.
Example:
#ManagedBean
#ViewScoped
public class MyManagedBean{
#PostConstruct
public void initView() throws Exception{
...initialize page values, execute database queries, etc.
}

JSF selectBooleanCheckbox not calling the associated setter method if it is conditionally rendered

I'm using Mojarra 2.0.3 on JBoss 6.1.0 final. I'm having a problem with the value setter method for an h:selectBooleanCheckbox not being called if conditional rendering is specified in the tag.
Specifically:
JSF:
<h:selectBooleanCheckbox value="#{somebean.checked}" rendered="#{somebean.render}" />
Example bean code:
private Boolean checked = new Boolean(false);
public Boolean getChecked() {return checked;}
public void setChecked(Boolean checked) {this.checked = checked;}
public boolean getRender() {return true;}
The problem is that the setChecked() method is never called when the form is submitted. If I remove the "rendered" attribute, the setter will be called as expected. It's only when the tag is conditionally rendered that it is not processed on submit. The getter is called normally in either case.
If I set a valueChangeListener, this is also not invoked if the selectBooleanCheckbox is conditionally rendered. Finally, enclosing the h:selectBooleanCheckbox tag in a container like an :panelGrid and setting the conditional rendering on the "outside" component results in the same behavior. It seems that the checkbox won't be processed if it is conditionally rendered.
This seems like kind of a basic thing, so I'm assuming there is something I'm missing. Does anyone have any similar experience with this?
UPDATE: The managed bean in this case is a CDI ConversationScoped bean. Further debugging seemed to suggest that another instance of the bean instantiated and used somewhere in the JSF lifecycle. So I modified the bean to set the conversation to non-transient in the postConstruct method. This caused JSF to throw the following exception while evaluating the EL expression used in the "rendered" attribute:
23:41:12,179 WARNING[javax.enterprise.resource.webcontainer.jsf.lifecycle] /admin/edit_user_profile.xhtml #41,72 rendered="#{profileEditor.isCurrentUser}": java.lang.IllegalStateException: javax.el.ELException: /admin/edit_user_profile.xhtml #41,72 rendered="#{profileEditor.isCurrentUser}": java.lang.IllegalStateException
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111) [:2.0.3-]
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190) [:2.0.3-]
at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:417) [:2.0.3-]
.
.
.
Caused by: java.lang.IllegalStateException
at com.sun.faces.context.FacesContextImpl.assertNotReleased(FacesContextImpl.java:635) [:2.0.3-]
at com.sun.faces.context.FacesContextImpl.getExternalContext(FacesContextImpl.java:135) [:2.0.3-]
at com.sgi.tds.web.admin.beans.TdsAdminBean.getCurrentUser(TdsAdminBean.java:36) [:]
at com.sgi.tds.web.admin.beans.UserProfileEditorBean.getIsCurrentUser(UserProfileEditorBean.java:153) [:]
at com.sgi.tds.web.admin.beans.UserProfileEditorBean$Proxy$_$$_WeldClientProxy.getIsCurrentUser(UserProfileEditorBean$Proxy$_$$_WeldClientProxy.java) [:]
As part of attack safeguard, the rendered attribute is re-evaluated when JSF postprocesses the form submit. That it evaluates false in your particular case can only mean that your bean is request scoped and that you didn't preserve the attribute value in bean's (post)constructor.
If you can't preserve it, then you need to put the bean in the view scope.
#ManagedBean
#ViewScoped
public class Somebean {
// ...
}
This way the bean instance lives as long as you're interacting with the same view. See also this related question/answer: commandButton/commandLink/ajax action/listener method not invoked or input value not updated

Resources