1 / 36

Message-Driven Bean(MDB)

Message-Driven Bean(MDB). Goals. Be able to produce messages from the EJB server Be able to consume messages within the EJB server Be able to define timers within EJB server. Objectives. EJB JMS Producers EJB JMS Consumers (Message Driven Beans; MDBs) Asynchronous Methods EJB Timers. 3.

Download Presentation

Message-Driven Bean(MDB)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Message-Driven Bean(MDB)

  2. Asynchronous EJB Goals • Be able to produce messages from the EJB server • Be able to consume messages within the EJB server • Be able to define timers within EJB server

  3. Asynchronous EJB Objectives • EJB JMS Producers • EJB JMS Consumers (Message Driven Beans; MDBs) • Asynchronous Methods • EJB Timers 3

  4. Asynchronous EJB EJB JMS Producers • Obtain Resources • ConnectionFactory • Destination • Create Session • integrate with JTA transaction • Publish Message 4

  5. Asynchronous EJB Obtaining a ConnectionFactory • Using annotations @Stateless public class SellerEJB ... { @Resource(mappedName=“java:/JmsXA") private ConnectionFactory connFactory; • mappedName points to global JNDI name • benefits • concise & simple • drawbacks • mixes deployment concepts with Java code 5

  6. Asynchronous EJB Obtaining a ConnectionFactory (cont.) • Using ejb-jar.xml <ejb-name>SellerEJB</ejb-name> <resource-ref> <res-ref-name>jms/ConnectionFactory</res-ref-name> <res-type>javax.jms.ConnectionFactory</res-type> <mapped-name>java:/JmsXA</mapped-name> <injection-target> <injection-target-class> ejava.examples.asyncmarket.ejb.SellerEJB </injection-target-class> <injection-target-name> connFactory </injection-target-name> </injection-target> </resource-ref> ... • mappedName moved away from code to DD • factory injected into EJB • ejb-jar.xml is no longer vendor/deployment-neutral 6

  7. Asynchronous EJB Obtaining a ConnectionFactory (cont.) • Using jboss-ejb3.xml <session> <ejb-name>SellerEJB</ejb-name> <resource-ref> <res-ref-name>jms/ConnectionFactory</res-ref-name> <jndi-name>java:/JmsXA</jndi-name> </resource-ref> </session> • mappedName is now removed • replaced with vendor/deployment specific reference • Required 3 files to complete v111128 Asynchronous EJB 7

  8. Asynchronous EJB Obtaining a Destination • Using annotations @Stateless public class SellerEJB implements SellerLocal, SellerRemote { ... @Resource(mappedName="java:/topic/ejava/examples/asyncMarket/topic1", type=Topic.class) private Destination sellTopic; • mappedName points to global JNDI entry • benefits • concise and simple • drawbacks • mixes deployment properties with implementation v111128 Asynchronous EJB 8

  9. Asynchronous EJB Obtaining a Destination (cont.) • Using ejb-jar.xml <resource-env-ref> <resource-env-ref-name>jms/sellTopic</resource-env-ref-name> <resource-env-ref-type>javax.jms.Topic</resource-env-ref-type> <mapped-name>topic/ejava/examples/asyncMarket/topic</mapped-name> <injection-target> <injection-target-class> ejava.examples.asyncmarket.ejb.SellerEJB </injection-target-class> <injection-target-name>sellTopic</injection-target-name> </injection-target> </resource-env-ref> • mappedName moved away from Java and to DD • note resource-env-ref used for Destinations v111128 Asynchronous EJB 9

  10. Asynchronous EJB Getting a Session @TransactionAttribute(TransactionAttributeType.REQUIRED) public long sellProduct(String sellerId, AuctionItem item) throws MarketException { Connection connection = null; Session session = null; try { connection = connFactory.createConnection(); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); ... } catch (JMSException ex) { log.error("error publishing sell", ex); ctx.setRollbackOnly(); throw new EJBException("error publishing sell:" + ex); } finally { try { if (session != null) { session.close(); } if (connection != null) { connection.close(); } } catch (JMSException ex) { log.error("unable to close resources", ex); } } } 10

  11. Asynchronous EJB Integrating JMS into the Transaction Person seller = sellerDAO.getPersonByUserId(sellerId); seller.getItems().add(item); item.setOwner(seller); auctionItemDAO.createItem(item); publishForSale(session, item); return item.getId(); 11

  12. Asynchronous EJB Publishing the Message protected void publishForSale(Session session, AuctionItem item) throws JMSException { MessageProducer producer = null; try { producer = session.createProducer(sellTopic); MapMessage message = session.createMapMessage(); message.setJMSType("forSale"); message.setLong("id", item.getId()); message.setString("name", item.getName()); message.setString("seller", item.getOwner().getUserId()); message.setLong("startDate", item.getStartDate().getTime()); message.setLong("endDate", item.getEndDate().getTime()); message.setDouble("minBid", item.getMinBid()); message.setDouble("bids", item.getBids().size()); message.setDouble("highestBid", (item.getHighestBid() == null ? 0.00 : item.getHighestBid().getAmount())); producer.send(message); } finally { if (producer != null) { producer.close(); } } } 12

  13. Asynchronous EJB EJB JMS Consumers; MDBs • “Message Driven Bean” • Introduced in EJB 2.0 to support JMS providers • Extended in EJB 2.1 to support non-JMS message providers • using the Java EE Connector API • commonly called JCA • EJB 3.0 added @Annotation support for configuration • Java EE Providers • must support a JMS provider • must support external providers through JCA • Session and Entity Beans cannot be a MessageListener • can poll for messages with MessageConsumer.receive() • can be wrapped by an MDB to be called asynchronously 13

  14. Asynchronous EJB MessageDriven Bean Configuration • Destination Type • Destination • Selector • Message Acknowledgement • ... 14

  15. Asynchronous EJB MDB Configuration • Using annotations @MessageDriven(name="BuyerMDB", activationConfig={ @ActivationConfigProperty( propertyName="destinationType", propertyValue="javax.jms.Topic"), @ActivationConfigProperty( propertyName="destination", propertyValue="topic/ejava/.../topic1"), @ActivationConfigProperty( propertyName="messageSelector", propertyValue= "JMSType in ('forSale', 'saleUpdate')"), @ActivationConfigProperty( propertyName="acknowledgeMode", propertyValue="Auto-acknowledge") }) public class BuyerMDB implements MessageListener { 15

  16. Asynchronous EJB MDB Configuration (cont.) • Using ejb-jar.xml <message-driven> <ejb-name>BuyerMDB</ejb-name> <ejb-class>ejava.examples.asyncmarket.ejb.BuyerMDB</ejb-class> <message-destination-type> javax.jms.Topic </message-destination-type> <activation-config> <activation-config-property> <activation-config-property-name> ... </activation-config-property-name> <activation-config-property-value> ... </activation-config-property-value> </activation-config-property> </activation-config> 16

  17. Asynchronous EJB MDB Configuration (cont.) • Using jboss.xml <message-driven> <ejb-name>BuyerMDB</ejb-name> <destination-jndi-name> topic/ejava/examples/asyncMarket/topic1 </destination-jndi-name> v111128 17

  18. MDB Structure @MessageDriven(name="BuyerMDB", activationConfig={ ... }) public class BuyerMDB implements MessageListener { @PostConstruct public void init() { ... } public void onMessage(Message message) { try { log.debug("onMessage:" + message.getJMSMessageID()); MapMessage auctionMsg = (MapMessage)message; long itemId = auctionMsg.getLong("id"); processAuctionItem(itemId); } catch (Exception ex) { log.error("error processing message", ex); } }

  19. Asynchronous EJB MDB and Transactions • SUPPORTED • message receipt/acknowledgement integrated with overall transaction • NOT_SUPPORTED • message receipt/acknowledgement independent of transactions within processing v111128 19

  20. Asynchronous Methods • Scenario • Task(s) may take considerable time to complete • Client need not wait for them to complete • @javax.ejb.Asynchronous • Return control to the client before EJB is invoked • Any session bean business method may be made @Asynchronous* (*see Serialization note below) • null return type • Client and issued task fully decoupled from one another • java.util.concurrent.Future return type • Allows task and client to coordinate a future return value • Client returns instance of javax.ejb.AsyncResult • Not Serializable (i.e., cannot use directly with RMI client)

  21. Synchronous Example: Client EJB @Stateless public class AuctionMgmtEJB implements AuctionMgmtRemote, AuctionMgmtLocal { private @EJB AuctionMgmtActionEJB actions; public void workSync(int count, long delay) { DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); long startTime = System.currentTimeMillis(); for (int i=0; i<count; i++) { log.info(String.format("%s issuing sync request, delay=%d", df.format(new Date()), delay)); Date date= actions.doWorkSync(delay); log.info(String.format("sync waitTime=%d msecs", System.currentTimeMillis()-startTime)); } long syncTime = System.currentTimeMillis() - startTime; log.info(String.format("workSync time=%d msecs", syncTime)); }

  22. Synchronous Example: Helper EJB @Stateless public class AuctionMgmtActionEJB { public Date doWorkSync(long delay) { DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); log.debug(String.format("sync method %d starting %d delay at %s", Thread.currentThread().getId(), delay, df.format(new Date()))); try { Thread.sleep(delay); } catch (Exception ex) { ... } Date now = new Date(); log.debug(String.format("sync method %d completed %d delay at %s", Thread.currentThread().getId(), delay, df.format(now))); return now; }

  23. Synchronous Example: Results 11:06:44,624 INFO [AuctionMgmtEJB:306] 11:06:44.612 issuing sync request, delay=3000 11:06:44,626 DEBUG [AuctionMgmtActionEJB:24] sync method 163 starting 3000 delay at 11:06:44.626 11:06:47,628 DEBUG [AuctionMgmtActionEJB:30] sync method 163 completed 3000 delay at 11:06:47,630 INFO [AuctionMgmtEJB:309] sync waitTime=3018 msecs 11:06:47,631 INFO [AuctionMgmtEJB:306] 11:06:47.631 issuing sync request, delay=3000 11:06:47,634 DEBUG [AuctionMgmtActionEJB:24] sync method 163 starting 3000 delay at 11:06:47.634 11:06:50,636 DEBUG [AuctionMgmtActionEJB:30] sync method 163 completed 3000 delay at 11:06:50,637 INFO [AuctionMgmtEJB:309] sync waitTime=6025 msecs 11:06:50,637 INFO [AuctionMgmtEJB:306] 11:06:50.637 issuing sync request, delay=3000 11:06:50,638 DEBUG [AuctionMgmtActionEJB:24] sync method 163 starting 3000 delay at 11:06:50.638 11:06:53,640 DEBUG [AuctionMgmtActionEJB:30] sync method 163 completed 3000 delay at 11:06:53.640 11:06:53,641 INFO [AuctionMgmtEJB:309] sync waitTime=9029 msecs 11:06:53,642 INFO [AuctionMgmtEJB:312] workSync time=9030 msecs

  24. Asynchronous Example: Client EJB @Stateless public class AuctionMgmtEJB implements AuctionMgmtRemote, AuctionMgmtLocal { public void workAsync(int count, long delay) { DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); long startTime = System.currentTimeMillis(); List<Future<Date>> results = new ArrayList<Future<Date>>(); for (int i=0; i<count; i++) { log.info(String.format("%s issuing async request, delay=%d", df.format(new Date()), delay)); Future<Date> date = actions.doWorkAsync(delay); results.add(date); log.info(String.format("async waitTime=%d msecs", System.currentTimeMillis()-startTime)); } for (Future<Date> f: results) { log.info(String.format("%s getting async response", df.format(new Date()))); try { Date date = f.get(); } catch (Exception ex) { throw new EJBException("unexpected error in future.get():"+ex);} log.info(String.format("%s got async response", df.format(new Date()))); } long asyncTime = System.currentTimeMillis() - startTime; log.info(String.format("workAsync time=%d msecs", asyncTime)); }

  25. Asynchronous Example: Helper EJB @Stateless public class AuctionMgmtActionEJB { @javax.ejb.Asynchronous public java.util.concurrent.Future<Date> doWorkAsync(long delay) { DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS"); log.debug(String.format("async method %d starting %d delay at %s", Thread.currentThread().getId(), delay, df.format(new Date()))); try { Thread.sleep(delay); } catch (Exception ex) { ... } Date now = new Date(); log.debug(String.format("async method %d completed %d delay at %s", Thread.currentThread().getId(), delay, df.format(now))); return new javax.ejb.AsyncResult<Date>(now); }

  26. Asynchronous Example: Results 11:06:53,650 INFO [AuctionMgmtEJB:325] 11:06:53.650 issuing async request, delay=3000 11:06:53,658 INFO [AuctionMgmtEJB:328] async waitTime=8 msecs 11:06:53,659 INFO [AuctionMgmtEJB:325] 11:06:53.659 issuing async request, delay=3000 11:06:53,659 DEBUG [AuctionMgmtActionEJB:41] async method 166 starting 3000 delay at 11:06:53.659 11:06:53,668 DEBUG [AuctionMgmtActionEJB:41] async method 167 starting 3000 delay at 11:06:53.668 11:06:53,668 INFO [AuctionMgmtEJB:328] async waitTime=18 msecs 11:06:53,669 INFO [AuctionMgmtEJB:325] 11:06:53.669 issuing async request, delay=3000 11:06:53,670 INFO [AuctionMgmtEJB:328] async waitTime=20 msecs 11:06:53,670 DEBUG [AuctionMgmtActionEJB:41] async method 168 starting 3000 delay at 11:06:53.670 11:06:53,671 INFO [AuctionMgmtEJB:331] 11:06:53.671 getting async response 11:06:56,667 DEBUG [AuctionMgmtActionEJB:47] async method 166 completed 3000 delay at 11:06:56,669 DEBUG [AuctionMgmtActionEJB:47] async method 167 completed 3000 delay at 11:06:56,669 INFO [AuctionMgmtEJB:339] 11:06:56.669 got async response 11:06:56,670 INFO [AuctionMgmtEJB:331] 11:06:56.670 getting async response 11:06:56,671 INFO [AuctionMgmtEJB:339] 11:06:56.671 got async response 11:06:56,672 DEBUG [AuctionMgmtActionEJB:47] async method 168 completed 3000 delay at 11:06:56,673 INFO [AuctionMgmtEJB:331] 11:06:56.672 getting async response 11:06:56,673 INFO [AuctionMgmtEJB:339] 11:06:56.673 got async response 11:06:56,674 INFO [AuctionMgmtEJB:342] workAsync time=3024 msecs

  27. Asynchronous EJB EJB Timers • Performs similar role of job schedulers • “cron” • Two types • Single-action • createTimer(Date expiration, Serializable info) • fires once at or after a specific time in the future • createTimer(long duration, Serializable info) • fires once after a specific delay period • Interval-timer • createTimer(Date intialExpiration, long intervalDuration, Serializable info) • continually fires every intervalDuration after the initialExpiration time • createTimer(long initialDuration, long intervalDuration, Serializable info) • continually fires every intervalDuration after the initialDuration delay 27

  28. EJB Timers • Original EJB Timer Service part of EJB 2.1 • EJB 3.0 added annotation-based extensions that eliminated inheritance-based solution requirements • EJB 3.1 provided an overhaul of the overall service • Added declarative scheduling • @javax.ejb.ScheduleExpression • @javax.ejb.Schedule

  29. Declarative Calendar Timer @Schedule(second="*/10", minute ="*", hour="*", dayOfMonth="*", month="*", year="*”, persistent=false) public void execute(Timer timer) { log.info("timer fired:" + timer); try { checkAuction(); } catch (Exception ex) { log.error("error checking auction", ex); } }

  30. Programmatic Calendar Timer ScheduleExpression schedule = new ScheduleExpression(); schedule.second("*/10"); schedule.minute("*"); schedule.hour("*"); schedule.dayOfMonth("*"); schedule.month("*"); schedule.year("*"); auctionMgmt.initTimers(schedule); public void initTimers(ScheduleExpression schedule) { cancelTimers(); log.debug("initializing timers, schedule="+schedule); timerService.createCalendarTimer(schedule); } @Timeout public void execute(Timer timer) { log.info("timer fired:" + timer); try { checkAuction(); } catch (Exception ex) { log.error("error checking auction", ex); } }

  31. Programmatic Interval Timer auctionMgmt.initTimers(10*1000); public void initTimers(long delay) { cancelTimers(); log.debug("initializing timers, checkItemInterval="+delay); timerService.createTimer(0,delay, "checkAuctionTimer"); } @Timeout public void execute(Timer timer) { log.info("timer fired:" + timer); try { checkAuction(); } catch (Exception ex) { log.error("error checking auction", ex); } }

  32. EJB Timers • Accessing TimerService • Using Annotations @Resource private TimerService timerService; • Getting Timers timerService.getTimers() • Cancelling Timers for (Timer timer : (Collection<Timer>)timerService.getTimers()) { timer.cancel(); } • Timers • associated with the EJB that created them • are automatically integrated into JTA transaction

  33. EJB Timer Callbacks • Using annotations public class AuctionMgmtEJB ... @Timeout public void execute(Timer timer) { try { checkAuction(); } catch (Exception ex) { log.error("error checking auction", ex); } } • Using interfaces public class AuctionMgmtEJB implements TimedObject, ... public void ejbTimeout(Timer timer) { ... } }

  34. javax.ejb.TimerService public interface javax.ejb.TimerService{ javax.ejb.Timer createTimer(long, java.io.Serializable) throws ...; javax.ejb.Timer createSingleActionTimer(long, javax.ejb.TimerConfig) throws ...; javax.ejb.Timer createTimer(long, long, java.io.Serializable) throws ...; javax.ejb.Timer createIntervalTimer(long, long, javax.ejb.TimerConfig) throws ...; javax.ejb.Timer createTimer(java.util.Date, java.io.Serializable) throws ...; javax.ejb.Timer createSingleActionTimer(java.util.Date, javax.ejb.TimerConfig) throws ...; javax.ejb.Timer createTimer(java.util.Date, long, java.io.Serializable) throws ...; javax.ejb.Timer createIntervalTimer(java.util.Date, long,javax.ejb.TimerConfig) throws ...; javax.ejb.Timer createCalendarTimer(javax.ejb.ScheduleExpression) throws ...; javax.ejb.Timer createCalendarTimer(javax.ejb.ScheduleExpression, javax.ejb.TimerConfig) throws ...; java.util.Collection getTimers() throws ...; }

  35. Asynchronous EJB Summary • EJB JMS Publishers • integrates into Session and MDB processing • EJB JMS Subscriber • implemented using MDB • MDBs support more than JMS using JCA • Asynchronous Methods • EJB Timers • schedule re-activation of Session Bean • Single-action and interval 35

  36. References • Java Messaging Service API • http://java.sun.com/javaee/5/docs/api/javax/jms/package-summary.html • “Enterprise JavaBeans 3.0, 5th Edition”; Burke & Monsen-Haefel; ISBN 0-596-00978-X; O'Reilly

More Related