Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Ejb3.0 Asynchronous Scheduler Without Threads


Published on

This is a simple J2EE pattern for creating, monitoring and controlling asynchronous job requests on the JBoss Application server using Web Services.

  • Be the first to comment

  • Be the first to like this

Ejb3.0 Asynchronous Scheduler Without Threads

  1. 1. EJB3.0 PatternsAsynchronous EJB3.0 Web Services on a Legacy EJB with management interface Michael Mountrakis Unified IT Services
  2. 2. The problemMy company decided to migrate to EJB an old legacyasynchronous application. The requirements are:● Re – use legacy code from the application● Define EJB3 design that : ● Employ Jboss Web Service calls to order jobs, gather job resoults, cancel jobs. ● Employ a Jboss service to monitor the job processing ● Comply with EJB3.0 standards Unified IT Services
  3. 3. Comply with EJB3.0 standards● Use J2EE annotations instead of XML deployment descriptors● Do not use threads● Do not use I/O● Benefit from EJB3.0 offered Jboss resources, like Pojo Services, JMX platform.... Unified IT Services
  4. 4. Design Synopsis● Design a Web Service to offer clients the ability to: to create requests, gather results, cancel requests.● Design a Jboss Service that will process WS calls and monitor the requests status.● Design a Stateless EJB that will perform the requests processing. Unified IT Services
  5. 5. Interfaces – Web ServiceClients can order Log Jobs, get Results and cancelthem: @Remote public interface LegacyProxyRemote { // Order a long job asyncronously int orderLongJobAsynch(String inData); // Query String Results for this request using Id String longJobResults( int jobId); // Cancel this request void longJobCancel( int jobId ); } Unified IT Services
  6. 6. Interfaces – JBoss Service LocalThe Web Service passes the clients requests toJboss Service. This service has local interface: @Local public interface LegacyServiceLocal{ //WS asks Service to call the EJB for this job int performLongJobAsynch(String inData); //WS queries the Service for Job Results String performLongJobResults(int jobId); //WS cancels the job void performLongJobCancel( int jobId); //EJB performing the job resisters its thread to the service void registerThread( int jobId, long threadId); } Unified IT Services
  7. 7. Interfaces – JBoss Service ManagementThe service has also management: @Management public interface LegacyServiceManagement { //JMX show the available job number int currentJobs(); //JMX Show Only those non delivered to the W-S String undeliveredJobs(); //JMX Show Active threads state of Threads Executing the long jobs – carrying the EJB... String threadsState(); //JMX Show – MBean Overriden cleanup void stop(); } Unified IT Services
  8. 8. Interfaces – Stateless EJBThe service manages the Legacy EJB that performsthe job. This EJB has local interface as follows: @Local public interface LegacyEjbLocal { //A long job that has String input and a String output. This may calls JNI, Oracle, AS400.... String performLongJob(int jobid, String inData); } Unified IT Services
  9. 9. Unified IT Services
  10. 10. Implementation: Web Service ● Web Service has a @EJB reference to the service:@Stateless@Remote(LegacyProxyRemote.class)@WebService@SOAPBinding(style = Style.RPC)public class LegacyProxyWS implementsLegacyProxyLocal, LegacyProxyRemote {@EJBLegacyServiceLocal service; Unified IT Services
  11. 11. Implementation Service ● The Jboss Service has a placeholder of all asynchronous proxies to the EJB. The service declaration is as follows:@Service(objectName = LegacyService.OBJECT_NAME)@Local(LegacyServiceLocal.class)@Management(LegacyServiceManagement.class)@LocalBinding(jndiBinding=LegacyService.JNDI_LOCAL)public class LegacyService implementsLegacyServiceManagement,LegacyServiceLocal { Unified IT Services
  12. 12. Implementation Service● The service utilizes the Legacy Beans performing asynhronous calls on them:@Overridepublic synchronized int performLongJobAsynch(String inData) {Integer key = generateKey();LegacyEjbLocal synchEjb = (LegacyEjbLocal)ctx.lookup(LegacyEjb.JNDI_LOCAL);LegacyEjbLocal asynchrEjb = AsyncUtils.mixinAsync(synchEjb);String ret = asynchrEjb.performLongJob(key, inData);ejbStore.put(key, synchEjb, asynchrEjb);return key;} The Asynchronous proxy The Asynchronous call. Notice that „ret“ is always a NULL string Unified IT Services
  13. 13. Implementation Service ● Here is how results are collected:@Overridepublic synchronized String performLongJobResults(int jobId) {Integer key = new Integer(jobId);LegacyEjbLocal asynchrEjb = ejbStore.getAsynch(key);Future<String> future = (Future<String>) AsyncUtils.getFutureResult(asynchrEjb);if (future.isDone()) {try {ret = (String) future.get();} catch (Exception e) {e.printStackTrace();} Unified IT Services
  14. 14. Implementation: ServiceThe service also monitors the thread state ofoperating EJBs carrying out the Long Jobs:@Overridepublic String threadsState() {//Get a reference to Jboss Thread manager:ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();Set<Integer> set = ejbStore.keySet();for (Integer i : set) {long tid = ejbStore.getThreadId(i);//Query the Jboss Thread manager for this thread idThreadInfo info = threadBean.getThreadInfo(tid);if( info != null)System.out.println(" thread state : " + info.getThreadState().toString() ) Unified IT Services
  15. 15. Implementation: Legacy EJB● The EJB performing the Long Job:@Stateless//@Stateful //can also be used...@Local( LegacyEjbLocal.class )@LocalBinding(jndiBinding=LegacyEjb.JNDI_LOCAL)public class LegacyEjb implements LegacyEjbLocal{ @Resource private SessionContext ctx;….. Unified IT Services
  16. 16. Implementation: Legacy EJB ● The EJB informs Service Monitor about the thread currently working on a request using a Local Reference, aquired with JNDI:public String performLongJob(int jobId, String inData) {try {LegacyServiceLocal service = (LegacyServiceLocal)ctx.lookup(LegacyService.JNDI_LOCAL);service.registerThread(jobId,Thread.currentThread().getId() );System.out.println("long job working...");Thread.sleep(60 * 1000);} Unified IT Services