Hi I have experimented #Inject annotation with cdi bean. I have one variable in first bean which is injected into second bean. When I call method on second bean using variable in first bean, during that method call first bean's variable returns null.
Here is xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Experiments</title>
</h:head>
<h:body>
<h:form id="main_form">
<h:inputText id="nameInput" value="#{myBean.name}"></h:inputText>
<h:commandButton value ="ok" action="#{myBean2.print()}">
<f:ajax execute="nameInput" render="nameOutput"/>
</h:commandButton>
<h:outputText id ="nameOutput" value="#{myBean2.name}"/>
</h:form>
</h:body>
</html>
beans:
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable
#Named(value = "myBean")
#SessionScoped
public class MyBean implements Serializable {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* Creates a new instance of myBean
*/
public MyBean() {
}
}
second bean: when I call print method of mybean2, injected myBean's 'name' property returns null.
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named
#Named(value = "myBean2")
#SessionScoped
public class MyBean2 implements Serializable{
String name;
#Inject
MyBean myBean;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String print(){
this.name = this.myBean.name;
return null;
}
/**
* Creates a new instance of myBean2
*/
public MyBean2() {
}
}
Is that normal or something wrong with code or config?
Related
i want use Primefaces BlockUI's widgetvar (at the moment i use a modal dialog for it). The application should block only when i select something (a long method will call) and unblock after complete. But it blocks the full side on first side access. Make i something wrong?
When i block the table specific it works. (block="table") But i want block the whole page.
Use Primefaces 5.1 & Mojarra 2.2.8
Short example:
xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>test</title>
</h:head>
<h:body>
<h:form>
<p:blockUI widgetVar="block" blocked="false"/>
<p:dataTable id="table" value="#{myController.tableItems}" rowKey="#{data}"
selection="#{myController.selectedItem}" selectionMode="Single"
var="data">
<p:ajax event="rowSelect" onstart="PF('block').show()"
listener="#{myController.doSomething}"
oncomplete="PF('block').hide()" />
<p:column>#{data}</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
Bean:
#ManagedBean
#ViewScoped
public final class MyController implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private List<String> tableItems;
private String selectedItem;
#PostConstruct
public void init() {
tableItems = new ArrayList<String>();
tableItems.add("test1");
tableItems.add("test2");
}
public void doSomething(SelectEvent event){
System.out.println("DO Something");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getSelectedItem() {
return selectedItem;
}
public void setSelectedItem(String selectedItem) {
this.selectedItem = selectedItem;
}
public List<String> getTableItems() {
return tableItems;
}
public void setTableItems(List<String> tableItems) {
this.tableItems = tableItems;
}
}
Add an id attribute the body and use that in the block= attribute on the blockui component
I have model class called Person and a view scope managed bean PersonController which contain a list of person
I have created a composite component that take this list of persons . What i want to do is to set the List of persons in other managed bean called TestCompositeComponent from the composite component directly .. Any solution ?.. This is my code :
#ManagedBean
#ViewScoped
public class PersonController {
private List<Person> persons;
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
#PostConstruct
public void init() {
persons = new ArrayList<>();
Person person1 = new Person();
person1.setFirstname("blah");
person1.setLastname("blah");
Person person2 = new Person();
person2.setFirstname("blah");
person2.setLastname("blah");
persons.add(person1);
persons.add(person2);
}
}
#ManagedBean
#ViewScoped
public class TestCompositeComponentController {
private List<Person> persons;
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html >
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface componentType="testCompositeController">
<composite:attribute name="persons" />
</composite:interface>
<composite:implementation>
<h:outputText value="composite"></h:outputText>
</composite:implementation>
</html>
<!DOCTYPE html >
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:test="http://java.sun.com/jsf/composite/test"
xmlns:f="http://java.sun.com/jsf/core">
<h:head></h:head>
<h:body>
<test:test persons="#{personController.persons}" />
</h:body>
</html>
Do you want to change the List persons passed from the PersonController to the TestCompositeComponentController back to PersonController?
If this is the case, change the scope of PersonController to #SessionScoped and inject it to TestCompositeComponentController. This way you will be able to modify the persons in the PersonController.
#ManagedBean
#ViewScoped
public class TestCompositeComponentController {
private List<Person> persons;
#Inject PersonController personController;
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
public void updateTheOtherList() {
personController.setPersons(this.persons);
}
}
In a real case scenario, the modifications in your composite component would be persisted in a database and when you navigate back the changes would be visible by a new fetch on the person list.
i am new to the icefaces components, want to use ice:selectInputText component same as in showcase [ice:selectInputText showcase][1] but the default css as it is shown in showcase doesnot functions same for me. i get dropdown list when something entered but the values shown as transparent rows and nothing highlited when move mouse on any item.
Can anyone guide where can be the problem:
here's my code:test.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ice="http://www.icesoft.com/icefaces/component">
<h:head></h:head>
<h:body>
<h:form>
<h:panelGroup>
<h:outputLabel value="Enter your name(autocomplete) :"></h:outputLabel>
<ice:selectInputText id="heloo"
value="#{helloBean.selectedItem}"
rows="10" width="152" valueChangeListener="#{helloBean.ValueChangeL}" actionListener="#{helloBean.ActionL}">
<f:selectItems value="#{helloBean.itemList}"></f:selectItems>
</ice:selectInputText>
</h:panelGroup>
</h:form>
</h:body>
</html>
Managed bean class:
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import com.icesoft.faces.component.selectinputtext.SelectInputText;
#ManagedBean( name= "helloBean")
#SessionScoped
public class HelloBean {
private String selectedItem;
private Integer seelectedId;
private List<SelectItem> itemList=new ArrayList<SelectItem>();
public String getSelectedItem() {
return selectedItem;
}
public void setSelectedItem(String selectedItem) {
this.selectedItem = selectedItem;
}
public Integer getSeelectedId() {
return seelectedId;
}
public void setSeelectedId(Integer seelectedId) {
this.seelectedId = seelectedId;
}
public List<SelectItem> getItemList() {
return itemList;
}
public void setItemList(List<SelectItem> itemList) {
this.itemList = itemList;
}
public void ValueChangeL(ValueChangeEvent event)
{
String query=(String) event.getNewValue();
System.out.println("query is "+query);
SelectItem item1=new SelectItem();
SelectItem item2=new SelectItem();
SelectItem item3=new SelectItem();
item1.setLabel("abc");
item1.setValue(1);
item2.setLabel("bbc");
item2.setValue(2);
item3.setLabel("aaa");
item3.setValue(3);
itemList.add(item1);
itemList.add(item2);
itemList.add(item3);
}
public void ActionL(ActionEvent event)
{
System.out.println("HELLO IN LISTENER of SELECTINPUTTEXT"+event.getSource().toString());
System.out.println("HELLO IN LISTENER of PHASEID IS"+event.getPhaseId());
if ( event != null && event.getSource() instanceof SelectInputText )
{
SelectInputText comp_ = (SelectInputText) event.getSource();
SelectItem selectItem_ = comp_.getSelectedItem();//critical line
System.out.println("selected id"+selectItem_.getValue());
seelectedId=(Integer)selectItem_.getValue();
}
}
public String submitFunc()
{
System.out.println("checking selected item: "+ selectedItem );
System.out.println("checking selected id: "+ seelectedId );
return "success";
}
}
There is more to the showcase than that is shown on the page. There are some stylesheets that are included on that page.
If you want to have the same kind of styling. Refer to their code base here and include those as well.
I created an ejb
#Stateless
#LocalBean
public class BasitBean {
public String helloBasit() {
return "Basit";
} //end of helloBasit()
} //end of class BasitBean
I am calling it from JSF like
<h:body>
<h:outputLabel value="#{helloBasit.callBasit()}" />
</h:body>
#ManagedBean
#SessionScoped
public class HelloBasit {
#EJB
private BasitBean basitBean;
/** Creates a new instance of HelloBasit */
public HelloBasit() {
}
public String callBasit() {
return basitBean.helloBasit();
} //end of callBasit()
} //end of class HelloBasit
This code is working fine. But when i change the code like this
<h:body>
<h:outputLabel value="#{helloBasit.label}" />
</h:body>
#ManagedBean
#SessionScoped
public class HelloBasit {
#EJB
private BasitBean basitBean;
String label;
/** Creates a new instance of HelloBasit */
public HelloBasit() {
System.out.println();
String label = basitBean.helloBasit();
System.out.println(label);
}
public BasitBean getBasitBean() {
return basitBean;
}
public void setBasitBean(BasitBean basitBean) {
this.basitBean = basitBean;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
} //end of class HelloBasit
Then i get the exception
SEVERE: Error Rendering View[/index.xhtml]
com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: pk.mazars.basitMahmood.HelloBasit.
at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:193)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:102)
......
Why i am getting this exception? The flow should be what i understand is when my page encounters #{helloBasit.label} then my constructor get call, instance variable get initialized, injected the bean instance into the basitBean, then the bean method should call. But i am getting null in the bean instance in this case why? Why previous code is working and it is not ? How can i call bean from the constructor ?
Thank you.
try to move your content of the constructor into a post constructor instead...
like this
#PostConstruct
private void init() {
System.out.println();
String label = basitBean.helloBasit();
System.out.println(label);
}
Cause the ejb bean should be injected only after the managed bean has been initiated
The #PostConstruct is being run after the constructor (after that the managed bean itself was created by the JSF) and only then the EJB is being injected into the bean and can be accessed...
Your idea is correct, but I see some things that may be fixed.
#LocalBean annotation is not required if your EJB is not directly implementing an interface. In this case, with or without the #LocalBean annotation you have the same effect. You may leave that if you want to make it explicit though. See this.
Make sure both #ManagedBean and #SessionScoped import from javax.faces.bean package.
Please, see this working sample:
EJB
import javax.ejb.Stateless;
#Stateless
public class PersonService {
public String getName() {
return "Cloud Strife";
}
}
Managed Bean
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class PersonBean {
#EJB
private PersonService ps;
private String name;
#PostConstruct
public void init() {
name = ps.getName();
}
public String getName() {
return name;
}
}
XHTML Page
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<f:view contentType="text/html">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h1>Welcome, #{personBean.name}</h1>
</h:body>
</f:view>
</html>
If your value should be loaded only once, say at your bean construction, always prefer a method with #PostConstruct annotation instead of the constructor.
Also, in order to call bean methods before rendering a view you could use a f:event tag, for example:
<f:event type="preRenderView" listener="#{personBean.init}" />
I hope it helps!
I'm using JBoss6.1.Final, JSF 2.0 (Mojarra), Weld CDI, MyFaces CODI 1.0.5 (for view-access-scoped)
I'm using something like the Gateway Pattern from Real World Java EE Patterns Rethinking Best Practices (unfortunately I don't have it with me, so I may have screwed something up here). Basically, the application allows a user to go into "edit mode" and edit a List of people (create, edit, remove) maintained in a #ViewAccessScoped backing bean with an extended persistence context and then click a "save" command link that flushes all their changes to the database. At first I was having a problem with ViewExpiredExceptions (if the browser was idle past the session-timeout period and then further requests are performed), but I added some jQuery to make a get request to a servlet that keeps the session alive (called 10 seconds before session-timeout). This seems to be working but now I have another problem, the backing bean is also a SFSB and after some idle time, it is being removed resulting in the following error message being logged (and all ajax rendered data disappears) when I attempt to perform more edits ...
13:06:22,063 SEVERE [javax.enterprise.resource.webcontainer.jsf.context] javax.el.ELException: /index.xhtml #27,81 rendered="#{!conversationBean.editMode}": javax.ejb.NoSuchEJBException: Could not find stateful bean: 43h1h2f-9c7qkb-h34t0f34-1-h34teo9p-de
Any ideas on how I could prevent SFSB removal or at least handle it more gracefully?
Here's my backing bean:
package com.ray.named;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJBTransactionRolledbackException;
import javax.ejb.Stateful;
import javax.ejb.TransactionAttribute;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ViewAccessScoped;
import com.ray.model.Person;
#Named
#Stateful
#ViewAccessScoped
#TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
public class ConversationBean implements Serializable {
private static final long serialVersionUID = 1L;
//properties
private List<Person> people;
private String name;
private Boolean editMode;
#PersistenceContext(type=PersistenceContextType.EXTENDED)
private EntityManager em;
#PostConstruct
public void init() {
people = em.createNamedQuery("Person.findAll", Person.class).getResultList();
setEditMode(false);
}
//event listeners
public void beginEdits() {
setEditMode(true);
}
public void addPerson() {
Person p = new Person(name);
em.persist(p);
people.add(p);
name = null;
}
public void removePerson(Person p) {
people.remove(people.indexOf(p));
em.remove(p);
}
//this method flushes the persistence context to the database
#TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRES_NEW)
public void saveEdits() {
setEditMode(false);
}
//getters/setters
public List<Person> getPeople() {
return people;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getEditMode() {
return editMode;
}
public void setEditMode(Boolean editMode) {
this.editMode = editMode;
}
}
Here's the Person entity bean:
package com.ray.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Version;
#Entity
#NamedQueries({
#NamedQuery(name="Person.findAll",
query="SELECT p FROM Person p")
})
public class Person {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String name;
#Version
private int version;
public Person() { }
public Person(String name) {
setName(name);
}
public boolean equals(Object o) {
if (!(o instanceof Person)) {
return false;
}
return id == ((Person)o).id;
}
//getters/setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
Here's the view:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
setInterval(function() {
$.get("#{request.contextPath}/poll");
}, #{(session.maxInactiveInterval - 10) * 1000});
});
</script>
<title>Conversation Test</title>
</h:head>
<h:body>
<h:form>
<h:commandLink value="Begin Edits" rendered="#{!conversationBean.editMode}">
<f:ajax render="#form" listener="#{conversationBean.beginEdits}"/>
</h:commandLink>
<h:commandLink value="Save" rendered="#{conversationBean.editMode}">
<f:ajax render="#form" listener="#{conversationBean.saveEdits}"/>
</h:commandLink>
<h:dataTable id="peopleTable" value="#{conversationBean.people}" var="person">
<h:column>
<f:facet name="header">Name</f:facet>
<h:panelGroup>
<h:inputText value="#{person.name}" disabled="#{!conversationBean.editMode}">
<f:ajax/>
</h:inputText>
<h:commandLink value="X" disabled="#{!conversationBean.editMode}">
<f:ajax render="#form" listener="#{conversationBean.removePerson(person)}"/>
</h:commandLink>
</h:panelGroup>
</h:column>
</h:dataTable>
<h:panelGrid columns="2">
<h:outputLabel for="name">Name:</h:outputLabel>
<h:inputText id="name" value="#{conversationBean.name}" disabled="#{!conversationBean.editMode}"/>
</h:panelGrid>
<h:commandButton value="Add" disabled="#{!conversationBean.editMode}">
<f:ajax execute="#form" render="#form" listener="#{conversationBean.addPerson}"/>
</h:commandButton>
</h:form>
</h:body>
</html>
Here's a servlet used to keep the session alive (called by jQuery ajax get request 10 seconds before session expires):
package com.ray.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PollServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init() throws ServletException {
}
public String getServletInfo() {
return null;
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.getSession(); //Keep session alive
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
}
public void destroy() {
}
}
Any ideas on how I could prevent SFSB removal or at least handle it
more gracefully?
To investigate further I would recommend to take a look at the EJB lifecycle hooks for passivation and add some debug output there.
Should that be the source of the problem you will be able to configure / deactivate passivation - but scalability might come up as an issue.
Honestly, this scenario seems quite uncommon to me. In general I would expect requests / conversations / sessions to be working more or less in the default boundaries - should you find yourself writing code that circumvents this can it be that you are better off with a RESTful / stateless approach...?
Please update the question with further information if available.
I suppose you have already solved your problem. Otherwise, this JBoss wiki page should be helpful (also for future readers...).
https://community.jboss.org/wiki/Ejb3DisableSfsbPassivation
Cheers,
Luigi