Problem with Asynchronous call and richfaces progressBar
freakwave10 May 10, 2009 11:03 PMHi all,
in a small wizard like application, I have an asynchronous method that subscribes to a Tibco JMS queue.
The application consists of 3 seam components:
1) statefull session bean supporting the wizard functionality
2) POJO for the progressBar
3) stateless session bean for the Tibco JMS queue subscriber
number 3) contains a subscribe() method that is defined with the @Asynchronous annotation in the Interface
I wait now for a short time to get a certain message. During that time, the progress Bar is displayed on the page.
Whenever the wizard page submits data in last step, the following happens:
- Record is inserted into a Oracle DB (XA Datasource)
- subscribe() is called on the Tibco JMS Queue stateless bean asynchronously
The whole process is working perfectly fine, well almost perfect, I always get the following exception in the log:
22:52:24,578 INFO [MeAccountWizardBean] subscribe - called 22:52:24,591 ERROR [GeneralPurposeDatabasePersistencePlugin] Cannot serialize: AsynchronousInvocation(tibcoJMSTopicSubscriber.subscribe()) java.io.NotSerializableException: com.weba.session.MeAccountWizardBean
when I also implement the Serializable Interface on the statefull session bean the error message points more to the ProgressBarBean:
22:52:24,578 INFO [MeAccountWizardBean] subscribe - called 22:54:53,722 ERROR [GeneralPurposeDatabasePersistencePlugin] Cannot serialize: AsynchronousInvocation(tibcoJMSTopicSubscriber.subscribe()) java.io.NotSerializableException: com.weba.session.ProgressBarBean
Here is my MeAccountWizardBean:
package com.weba.session; import java.io.Serializable; import javax.ejb.Remove; import javax.ejb.Stateful; import javax.jms.JMSException; import javax.jms.ObjectMessage; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; import javax.persistence.Query; import org.jboss.seam.Component; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Begin; import org.jboss.seam.annotations.Destroy; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Transactional; import org.jboss.seam.log.Log; import com.weba.session.MeAccountWizard; @Stateful @Name("meAccountWizardBean") public class MeAccountWizardBean implements MeAccountWizard, JmsCallBackIf, Serializable { private static final long serialVersionUID = 1L; private String creationType = "ownAccount"; private String fmnoEntered; private String chargeCode; private String conferenceName; private String contactName; private String fmno; private String firstName; private String lastName; private boolean progressBarEnabled; private Long currentValue; private MeetingExchangeAccountDO meDO; private boolean progressBarResultPanelEnabled = false; private boolean wizardSuccess = false; private boolean wizardFailed = false; private boolean audioConferenceConfirm = true; private String message; @PersistenceContext(type = PersistenceContextType.EXTENDED, unitName = "AudioConference") EntityManager em; @In(create = true, value = "progressBarBean") ProgressBarBean progressBarBean; @Logger Log log; @Begin(pageflow = "AccountCreation") public void startWizard() { log.info("startWizard"); } public void jmsReceived(javax.jms.Message jmsMessage) { log.info("jmsReceived"); this.progressBarEnabled = false; if (jmsMessage != null) { this.wizardSuccess = true; this.wizardFailed = false; log.info("jmsReceived - jmsMessage: " + jmsMessage); ObjectMessage m = (ObjectMessage) jmsMessage; try { meDO = (MeetingExchangeAccountDO) m.getObject(); } catch (JMSException e) { log.error("jmsReceived - JMSException" + e.getMessage()); } } else { log.info("jmsMessage - message is null"); this.wizardSuccess = false; this.wizardFailed = true; this.message = "no message received"; } } public void subscribe() { log.info("subscribe - called"); TibcoJMSTopicSubscriberIf tibcoJMSTopicSubscriber = (TibcoJMSTopicSubscriberIf) Component .getInstance("tibcoJMSTopicSubscriber", ScopeType.STATELESS, true); tibcoJMSTopicSubscriber.subscribe(this); this.audioConferenceConfirm = false; this.progressBarResultPanelEnabled = true; } public Long getCurrentValue() { if (this.progressBarEnabled) { currentValue = progressBarBean.getCurrentValue(); log.info("getCurrentValue - " + currentValue); } else { progressBarBean.setEnabled(false); currentValue = progressBarBean.getCurrentValue(); log.info("getCurrentValue - Else: " + currentValue); } return currentValue; } @Transactional public String confirmMeAccount() { try { progressBarBean.startProcess(); this.progressBarEnabled = true; String insertQueryStr = "INSERT INTO MAC_USER.AUDIO_CONF_REQUEST_V2 (DATE_SUBMITTED, FMNO, CHARGE_CODE, CONFERENCE_NAME, CC_NAME) VALUES (SYSDATE, '25090', 'ZXL668', 'MYTEST', 'DummyUser')"; Query insertQuery = em.createNativeQuery(insertQueryStr); insertQuery.executeUpdate(); } catch (Exception ex) { log.info("confirmMeAccount - Exception: " + ex.getMessage()); em.getTransaction().rollback(); return "Not Confirmed"; } subscribe(); return "confirmed"; } // action method after the user submitted the account creation type // returns the creation Type from the form which triggers a page redirect // based on the page flow xml public String submittedAccountCreationType() { return creationType; } public String getCreationType() { return creationType; } public void setCreationType(String creationType) { this.creationType = creationType; } public String getFmnoEntered() { return fmnoEntered; } public void setFmnoEntered(String fmnoEntered) { this.fmnoEntered = fmnoEntered; } public String getChargeCode() { return chargeCode; } public void setChargeCode(String chargeCode) { this.chargeCode = chargeCode; } public String getConferenceName() { return conferenceName; } public void setConferenceName(String conferenceName) { this.conferenceName = conferenceName; } public String getContactName() { return contactName; } public void setContactName(String contactName) { this.contactName = contactName; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getFmno() { return fmno; } public void setFmno(String fmno) { this.fmno = fmno; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public boolean isProgressBarEnabled() { return progressBarEnabled; } public void setProgressBarEnabled(boolean progressBarEnabled) { this.progressBarEnabled = progressBarEnabled; } public void setCurrentValue(Long currentValue) { this.currentValue = currentValue; } public boolean isProgressBarResultPanelEnabled() { return progressBarResultPanelEnabled; } public void setProgressBarResultPanelEnabled( boolean progressBarResultPanelEnabled) { this.progressBarResultPanelEnabled = progressBarResultPanelEnabled; } public boolean isWizardSuccess() { return wizardSuccess; } public void setWizardSuccess(boolean wizardSuccess) { this.wizardSuccess = wizardSuccess; } public boolean isWizardFailed() { return wizardFailed; } public void setWizardFailed(boolean wizardFailed) { this.wizardFailed = wizardFailed; } public boolean isAudioConferenceConfirm() { return audioConferenceConfirm; } public void setAudioConferenceConfirm(boolean audioConferenceConfirm) { this.audioConferenceConfirm = audioConferenceConfirm; } public MeetingExchangeAccountDO getMeDO() { return meDO; } public void setMeDO(MeetingExchangeAccountDO meDO) { this.meDO = meDO; } @Remove @Destroy public void destroy() { } }
Here the ProgressBarBean:
package com.weba.session; import java.util.Date; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.Scope; import org.jboss.seam.log.Log; @Name("progressBarBean") @Scope(ScopeType.PAGE) public class ProgressBarBean { private boolean buttonRendered = true; private boolean enabled = false; private Long startTime; private int currentValue = -1; @Logger Log log; public ProgressBarBean() { } public String startProcess() { log.info("startProcess"); setEnabled(true); setButtonRendered(false); setStartTime(new Date().getTime()); return null; } public Long getCurrentValue() { if (isEnabled()) { log.info("getCurrentValue - current value: " + currentValue); Long current = ((new Date().getTime() - startTime) / 1000) * 10; if (current > 100) { return new Long(101); } else if (current.equals(0)) { return new Long(1); } return ((new Date().getTime() - startTime) / 1000) * 10; } if (startTime == null) { return Long.valueOf(-1); } else { return Long.valueOf(101); } } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public Long getStartTime() { return startTime; } public void setStartTime(Long startTime) { this.startTime = startTime; } public boolean isButtonRendered() { return buttonRendered; } public void setButtonRendered(boolean buttonRendered) { this.buttonRendered = buttonRendered; } }