System and method of providing an asynchronous interface between a client system and an enterprise javabeans-enabled server

A method of implementing an interface to achieve asynchronous method invocations between a client system, a messaging server, and an enterprise JavaBeans-enabled server is provided which includes performing a lookup operation for an asynchronous home interface on JNDI directory service, returning a reference to the asynchronous home interface of an enterprise bean, to the client system, and making a call on the reference. The method also includes providing a listener for the asynchronous home interface to monitor a plurality of events, generating an event, receiving a result after generating the event; and executing a method of the listener.

DETAILED DESCRIPTION OF THE PREFERRED EMBODIMENT The present invention expands on the EJB synchronous method invocation paradigm defined in the EJB specification to create an interface for implementing asynchronous method invocations to provide a scalable, reliable and configurable infrastructure to integrate distributed and diverse applications, without generating dependencies on messaging services or platforms. This combination of standards compliance and customizability is one feature of the present invention. The present invention also allows the communication protocol's access to an enterprise bean to be completely transparent to the client system. In various embodiments, the present invention enables synchronous method invocations, asynchronous method invocations or both simultaneously on an enterprise java bean. With reference to FIG. 5 , there is shown an EJB architecture 22 having a client system 24 , a messaging server (interchangeably referred to herein as messaging service) 26 , and an EJB-enabled server 28 having a messaging engine and configured to provide asynchronous messaging at the container level using the messaging engine. The client system includes a client library 25 that is used to route messages from the client system to the messaging server and the EJB-enabled server. The client library may also be part of the messaging engine. The client system accesses the bean through the messaging server 26 using a method call provided by the client library. The messaging server 26 provides guaranteed message delivery. Examples of messaging servers 26 include IBM's MQ server and Oracle's AQ server. The EJB architecture may be implemented using one or more client systems, messaging servers, and EJB-enabled servers. This EJB architecture or any other architecture may be used to implement the asynchronous interface of the present invention. The interface can be implemented using hardware, software, or a combination of the two. For example, the interface can be the hardware that provides asynchronous communication between the client system and the messaging server and the messaging server and the EJB-enabled server. Also, the interface can be the software that is used to provide asynchronous communication between the client system and the messaging server and the messaging server and the EJB-enabled server. The interface of the present invention enables the client system to listen to messaging events and be notified when they occur, and therefore, the client system is informed when the result arrives. The result that the client system receives is in the form of a VandaMessagingEvent object and the results can be obtained from this object. The interface can be used to plug into any commercially available messaging server 16 (e.g., Oracle AQ, IBM MQ Series, etc.), including any JMS implementation. One feature of the present invention is that the asynchronous client interface is generic in the sense that the client contract hides the messaging calls so that the application programmer does not have to explicitly code them. This allows a program to be written in a general manner while the specifics of any particular asynchronous communication protocol are handled by choosing an asynchronous data link layer at the time of deployment. The interface also modifies the client contract defined in the EJB specification in a way such that normal applications (which are written in a manner compliant with the EJB specification) are not affected by the interface. The EJB specification provides for data link-specific containers that do not allow for a generic interface. As a consequence, asynchronous capability may only be provided at the application level (where transactional integrity is lost), not the container level (as in the present invention). The present invention ensures that the client system does not make any explicit messaging calls like the normal EJB-JMS implementation. The interface of the present invention helps facilitate asynchronous method invocations so that by the pooling of requests or the transmission of the requests to a remote location, the client system is available to process additional requests from users without the current application incurring server delays. Asynchronous communication is achieved by modifying the client contract to accommodate asynchronous method invocation. The client contract is modified so that the messaging container does not become incompatible with conventional client systems using the default EJB method invocation mechanism. FIG. 6 is a simplified block diagram of the interface between the client system and the EJB-enabled server of FIG. 5 wherewith a container is illustrated as providing the interface that facilitates synchronous and asynchronous method invocations simultaneously. A standard EJB application 40 a can obtain a normal home interface reference through JNDI 42 a . Whereas an application that requires asynchronous behavior 40 b can request an asynchronous home interface via JNDI 42 b . The two applications can respectively, simultaneously invoke methods synchronously and asynchronously on the same enterprise java bean deployed in the container enabled to handle asynchronous method invocations 44. Interface Specification The following sections describe a method of developing an interface to achieve asynchronous method invocations between the client system and any EJB-enabled server without explicitly making any messaging-specific calls. The following sections are divided up as follows: 1. Client-side implementation; 2. Bean-side implementation; 3. API Reference; and 4. Example. 1. Client-side implementation The following description refers to FIG. 7 , which is a simplified flow chart describing a method of developing a client side implementation of the interface of the present invention to achieve asynchronous method invocations in an EJB-enabled server. Since the present invention deals with asynchronous method calls, the result is not returned immediately, and therefore, the EJB architecture uses a mechanism, e.g., a listener, by which a notification is generated and acknowledged when a result arrives. Events from asynchronous remote method invocations are triggered, i.e., fire, when the result arrives. That is, when the result arrives, an event is generated. One or more listeners (mechanisms for receiving an event or result from a previous remote method call) can register to be notified about the events. Event handlers can be instances of any class. As long as the class implements a VandaMessagingEventListener interface, its instances can handle events. To invoke a remote bean's method asynchronously 1. Call Lookup Asynchronous Home Interface Reference on JNDI (Java Naming and Directory Interface) initial context with VMS as the protocol name (step A-2). 2. Add a listener to the Asynchronous Home Interface Reference returned by the Lookup (step A-4). 3. Call a method on the Asynchronous Home Interface Reference, which returns a CallID (step A-6). 4. Store the CallID returned by the method. To receive and process the response 1. After the above method is executed, the methodCompleted( ) method is executed and if an exception is returned then the exception( )Occurred( ) method is executed. 2. These methods use a CallID (available from event.getCallID()) to identify the call which was completed. 3. These methods use a getResult( ) method to get the result for the call (e.g., if it is a create( ) method of Home), getResult( ) will return Messaging<<Bean>>Remotelnterface. This result is used by the client system for subsequent operations (step A-8). As the present invention deals with asynchronous calls, the result is not returned immediately and therefore it is important to monitor when the result of a call is returned. One way to do this is to monitor for events. When the result arrives, an event is generated. One or more listeners can register to be notified about events. This also allows the programmer to delegate authority for event handling to the client library, which may be part of the client system 24 , as opposed to having the programmer query for the results. The business method used to implement the call lookup on the JNDI is described below. A. Call Lookup on JNDI To implement the call lookup, the client system calls lookup on the JNDI InitialContext with “VMS” 0 (used in this example to signify asynchronous) as the protocol name. For example, if the client system is looking for the Home Interface of an Account Bean, the client code might be as follows (see also FIG. 6 ): 1 Context ctx &equals; new InitialContext ( ); AsyncMessagingAccountHomeInterface ref &equals; ctx.lookup(“vms://AccountHomeInterface”); In this example, the lookup returns an AsyncMessagingAccountHomelnterface to enable the client system to obtain a reference to the asynchronous home interface of the respective bean. This reference enables the client system to make asynchronous calls on the bean without having a user write any messaging calls. The asynchronous home interface is automatically generated during deployment and configuration of the enterprise bean. An example of the actual bean interface and the generated asynchronous home interface is shown below: Actual Remote Interface of a StudentBean 2 import javax.ejb.*; import java.rmi.*; import java.util.*; public interface StudentEntityCMPRemoteInterface extends javax.ejb.EJBObject &lcub; // All business methods of Remote Interface public String computeGrade( ) throws RemoteException; public int getId( ) throws RemoteException; public void setId(int id) throws RemoteException; public String getName( ) throws RemoteException; public int getMarks( ) throws RemoteException, public void setName(String name) throws RemoteException; public void setMarks(int marks) throws RemoteException; public void swapRecords(int recordId) throws RemoteException; public void removeAndUpdateRecord(int recordId) throws RemoteException; public void removeRecord(int recordId) throws RemoteException, public void updateRecord(int recordId) throws RemoteException; public String getCallerName( ) throws RemoteException; public boolean getRollback( ) throws RemoteException; public void setRollback( ) throws RemoteException; public void createRecs( ) throws RemoteException; &rcub; The following code represents the corresponding generated asynchronous home interface: 3 import java.util.*; import java.rmi.*; import java.security.*; import vanda.generic.client.*; import vanda.client.messaging.*; import javax.ejb.*; public interface AsyncStudentEntityCMPRemoteInterface &lcub; // All business methods ... public long getName( ) throws java.rmi.RemoteException; public long setName(java.lang.String param0) throws java.rmi.RemoteException; public long removeRecord(int param0) throws java.rmi.RemoteException; public long computeGrade( ) throws java.rmi.RemoteException; public long createRecs( ) throws java.rmi.RemoteException; public long getCallerName( ) throws java.rmi.RemoteException; public long getId( ) throws java.rmi.RemoteException; public long getMarks( ) throws java.rmi.RemoteException; public long getRollback( ) throws java.rmi.RemoteException; public long isCallerInRole(java.lang.String param0) throws java.rmi.RemoteException; public long removeAndUpdateRecord(int param0) throws java.rmi.RemoteException; public long setId(int param0) throws java.rmi.RemoteException; public long setMarks(int param0) throws java.rmi.RemoteException; public long setRollback( ) throws java.rmi.RemoteException; public long swapRecords(int param0) throws java.rmi.RemoteException; public long updateRecord(int param0) throws java.rmi.RemoteException; // Other Utility business methods given as a part of the client interface public Object getResult(long callId) throws Exception; public boolean getStatus(long callId) throws VandaResultAlreadyReceivedException public void releaseMessagingService( ); // all Other EJB business methods - Given an Async Look public long getHandle( ) throws RemoteException; public long remove( ) throws RemoteException; public void addListener(VandaMessagingEventListener e); public VandaMessagingStub getEJBHome( ); public Object getPrimaryKey( ); public boolean isIdentical(Object obj); &rcub; For the above generated asynchronous remote interface, all the business methods are configured to return a long value to differentiate the asynchronous interface for each client system. When the client system invokes the methods, the methods return a long value called a CallID. The CallID is used by the client system when results arrive, to identify the appropriate method called. When implementing a synchronous call, the result returned is the actual value (or error exception); however, when implementing an asynchronous call, the result returned is not the actual value but rather an identifier (such as a CallID or other unique identifier), which can be used to retrieve the actual value returned from the asynchronous call. Implementations of the present invention to achieve asynchronous method invocations, cause the calls made on the reference to be converted to messaging calls by the client library thereby hiding the messaging calls that would normally have to be made by the programmer. The reference given to the client systems are used to instantiate and generate asynchronous stubs. An example of the code used to instantiate and generate the asynchronous stubs is shown below. 4 import java.lang.*; import java.util.*; import java.sql.*; import java.rmi.*; import java.security.*; import java.io.*; import javax.ejb.*; import vanda.generic.client.*; import vanda.client.messaging.*; import vanda.generic.messaging.*; import vanda.generic.container.core.*; import vanda.generic.server.core.*; public class AsyncVandaStudentEntityCMPRemoteInterface Impl_Stub extends VandaMessagingStub implements AsyncStudentEntityCMPRemoteInterface , Serializable &lcub; public AsyncVandaStudentEntityCMPRemoteInterface Impl_Stub( ) &lcub; setClassName(“StudentEntityCMPRemoteInterface”); setIsSession(false); &rcub; public long getName( ) throws java.rmi.RemoteException &lcub; VandaMessagingAPIInterface vandaAPI &equals; getVandaMessaging API( ); VandaMessagingArgument vandaMesgArgs; long methodCallId; vandaMesgArgs &equals; new VandaMessagingArgument( ); vandaMesgArgs.setClassName(“StudentEntityCMPRemote Interface”); vandaMesgArgs.setMethodName(“getName”); if (VandaMessagingClient.isJavaClient( ) &equals; &equals; false) &lcub; vandaMesgArgs.setSessionId(VandaMessagingClient.getSession Id( )); &rcub; vandaMesgArgs.setCallId(methodCallId &equals; VandaMessagingClient.getCallId( )); vandaMesgArgs.setSecurityId(getSecurityId( )); vandaMesgArgs.setTransactionContext(getTransaction Context( )); vandaMesgArgs.setRemoteObjectId(getObjectId( )); vandaMesgArgs.setClientId(getClientId( )); vandaMesgArgs.setConsumerName(getConsumerName( )); vandaMesgArgs.setObjectType( VandaMessagingObjectType.EJB_OBJECT); vandaMesgArgs.setTargetMessagingDescriptor( getTargetMessagingDescriptor( )); registerMethodCall(vandaMesgArgs); invokeMethod(vandaMesgArgs, “StudentEntityCMP”); return( methodCallId); &rcub; ......... // Similarly as the above business method, all other business methods are also implemented &rcub; As shown in the above code, the stub layer does not contain any direct messaging calls, rather, messaging objects are used for inserting messages into and retrieving messages from the messaging service 26 (see also FIG. 5 ). This plug-in implementation (or plug-in module) is a component of the EJB-enabled server and is dependent on the underlying messaging server 26 . Each method described above builds a Messaging Argument object that contains details about the bean, the method to be called on that bean, parameters, their types, etc. The Messaging Argument object is used at the server side to call the correct method. After building this object, the request object is registered with the client library for event notification. After the object is built, the stub calls invokeMethod which performs one or more of the following: 1. Enqueue the message into the messaging server 26 using the plug in module; or 2. Call the method directly if the client system is another bean and the target bean is also available at the same server. The following is a generic interface that may be implemented to develop plug-in modules, which are messaging server dependent. The generic asynchronous stubs can use an implementation of the interface (described below) for inserting messages into and retrieving messages from the messaging server 26 . 5 package vanda.generic.messaging; import vanda.server.core.*; public interface VandaMessagingAPIInterface &lcub; public void setMessagingDescriptor(VandaMessagingDescriptor Interface mesgDesc); public VandaMessagingDescriptorInterface getMessaging Descriptor( ); public void setproxyMessagingDescriptor( VandaProxyMessagingDescriptorInterface mesgDesc); public VandaProxyMessagingDescriptorInterface getProxyMessagingDescriptor( ); public boolean isClientProxy( ); public void enqueue (Object data) throws VandaMessagingEnqueue Exception; public void enqueue (Object data, String consumerName) throws VandaMessagingEnqueueException; public Object dequeue( ) throws VandaMessagingDequeueException; public Object dequeue(String consumerName) throws VandaMessagingDequeueException; public Object dequeueNoWait( ) throws VandaMessagingDequeue Exception; public Object dequeueNoWait(String consumerName) throws VandaMessagingDequeueException; public void enqueue (Object data, String consumerName, VandaMessagingDescriptorInterface mesgDesc) throws VandaMessagingEnqueueException; public Object browse( ) throws VandaMessagingOperationNot AllowedException; public void setSendTimeout(int timeout) throws VandaMessagingOperationNotAllowedException; public void setReceiveTimeout(int timeout) throws VandaMessagingOperationNotAllowedException; public boolean isMessageTimeoutSupported ( ); public boolean isReceiveTimeoutSupported ( ); public boolean isBrowseSupported ( ); public int getSendTimeout( ) throws VandaMessagingOperationNotAllowedException; public int getReceiveTimeout( ) throws VandaMessagingOperationNotAllowedException; public void releaseMessagingService( ); &rcub; The above code refers to an object called Messaging Descriptor, which is a generic object that contains details about the messaging server 26 . Details like topic name, queue name, etc. can be stored into this object. This object is kept opaque at the listener level for purposes of generality, but are interpreted at the messaging service 26 plug-in. The following code is a sample implementation of the plug in module using JMS messaging calls and a publish subscribe method for communication: public class VandaMessagingJMSImplementation 6 implements VandaMessagingAPIInterface &lcub; ............. public void setMessagingDescriptor (VandaMessagingDescriptor Interface mesgDesc) &lcub; mesgDescriptor &equals; mesgDesc; topicConnectionFactory &equals; new com.sun.messaging.TopicConnectionFactory (jmsAddress, mesgDescriptor.getPortNumber( )); topicConnection&equals; topicConnectionFactory.createTopicConnection(mesgDescriptor. getUserID( ),mesgDescriptor.getPassword( )); topicConnection.start( ); topicSessionEnqueue &equals; topicConnection.createTopicSession (false,1); topicSessionDequeue &equals; topicConnection.createTopicSession (false,1); &rcub; public VandaMessagingDescriptorInterface getMessagingDescriptor ( )&lcub; return mesgDescriptor; &rcub; public void enqueue (Object data) throws VandaMessagingEnqueue Exception&lcub; String topicName; String consumerName; consumerName &equals; mesgDescriptor.getConsumerName( ); topicName &equals; mesgDescriptor.getTopicName( ); topic &equals; topicSessionEnqueue.createTopic(topicName); topicPublisher &equals; topicSessionEnqueue.createPublisher(topic); objMessage &equals; topicSessionEnqueue.createObjectMessage( ); enqueueflag&equals;true; objMessage.setObject((Serializable)data); objMessage.setStringProperty(“ConsumerName”, consumerName); topicPublisher.publish(objMessage); &rcub; /** * enqueue(Object data ,String consumerName) puts the Message Object into the messaging service with the * details got from the messaging descriptor and the consumerName. */ public void enqueue (Object data, String consumerName) throws VandaMessagingEnqueueException&lcub; String topicName; topicName &equals; mesgDescriptor.getTopicName( ); topic &equals; topicSessionEnqueue.createTopic(topicName); topicPublisher &equals; topicSessionEnqueue.createPublisher(topic); objMessage &equals; topicSessionEnqueue.createObjectMessage( ); enqueueflag&equals;true; objMessage.setObject((Serializable)data); objMessage.setStringProperty(“ConsumerName”, consumerName); topicPublisher.publish(objMessage); &rcub; public Object dequeue( ) throws VandaMessagingDequeueException&lcub; String topicName; String consumerName; topicName &equals; mesgDescriptor.getTopicName( ); consumerName &equals; mesgDescriptor.getConsumerName( ); topic &equals; topicSessionDequeue.createTopic(topicName); topicSubscriber &equals; topicSessionDequeue.createSubscriber(topic, “ConsumerName &equals; “&plus; consumerName &plus;”” false); ObjectMessage objMessage &equals; (ObjectMessage)topicSubscriber. receive( ); return objMessage.getObject( ); &rcub; public Object browse( ) throws VandaMessagingOperationNot AllowedException &lcub; throw new VandaMessagingOperationNotAllowedException (“G003”); &rcub; public boolean isMessageTimeoutSupported ( )&lcub; return false; &rcub; public boolean isReceiveTimeoutSupported ( )&lcub; return false; &rcub; public boolean isBrowseSupported ( )&lcub; return false; &rcub; public void releaseMessagingService( )&lcub; topicPublisher.close( ); topicSubscriber.close( ); topicSessionEnqueue.close( ); topicSessionDequeue.close( ); topicConnection.close( ); topicConnectionFactory &equals; null; &rcub; ...................... TopicConnectionFactory topicConnectionFactory; TopicConnection topicConnection; TopicSession topicSession; TopicPublisher topicPublisher; TopicSubscriber topicSubscriber; Topic topic; VandaMessagingDescriptorInterface mesgDescriptor; ................ &rcub; The business method used to add a listener is described below. B. Adding a Messaging Event Listener Event handlers can be instances of any class. To be an event handler, a class has to implement the VandaMessagingEventListener interface. By doing so, the instances of the class can handle events. The user needs to add a listener to the home interface reference retrieved as a result of the lookup operation or on a remote interface retrieved as a result of any operation performed on the home interface (step A-10). An example of the code for adding a listener is as follows: ref.addListener (listener); where ref is the home interface or remote interface reference and listener is the instance of any class which implements VandaMessagingEventListener. For example, it may be an instance of Listenerlmpl. 7 public class ListenerImpl implements VandaMessagingEventListener &lcub; public void methodCompleted(VandaMessagingEvent resEvent) &lcub; resEvent.getResult( ); //will return the result &rcub; public void exceptionOccurred(VandaMessagingEvent resEvent) &lcub; // handle the exceptions &rcub; &rcub; Listeners enable the client system to receive the results of any call without having to query for them. In a normal asynchronous scenario, the client system would have to query for the result of an asynchronous call during the time when the result is unknown. In the case of listeners, the user is able to obtain the result and process it without having to write code to query for the result. The business method used to call a method on the bean is described below. C. Calling a Method on the Bean In the case of an asynchronous call to the enterprise bean, the call to any method on the reference might not be different from a normal invocation except that the return value for the asynchronous call might be different. For example, when the create() method is called on an enterprise bean's MessagingHomeInterface, a unique CallID is returned as opposed to the normal return value of a RemoteInterface (step A- 12). The code for the call is as follows: long createCallId&equals;ref.create(....); where createCallld is the variable in which the CallID is stored and ref represents the home interface reference. This is done since asynchronous methods do not return a value immediately. In order to be able to identify the call at a later time, the call returns a unique ID. The client program can then use this ID to identify the result when it arrives. D. Receiving and Processing the Result Once an event has been generated (step A-14), the result in the case of an asynchronous invocation of a bean can return either the intended return value or an exception (step A-16). If the method invocation is successful, the methodCompleted( ) method of the listener is executed (A- 18) and if an exception occurred (step A- 17), the exceptionOccurred( ) method of the listener is executed. In the methodCompleted( ) method and the exceptionOccurred( ) method, the VandaMessagingEvent is passed as a parameter. The VandaMessagingEvent class has the following three methods: &lsqb;a&rsqb; getCallID() (step A-20) This method returns the CallID that was generated when the client application called a particular method on the MessagingHomeInterface of the bean. This can be compared with the ID stored at the time of the bean method invocation to identify the call that generated this result. &lsqb;b&rsqb; getsource( ) (step A-21) This method returns the source of the event. For example, if the user had called the create( ) method on the MessagingAccountHomelnterface, this may return a string containing MessagingAccountHomelnterface:create. This string contains the name of the interface that contained the bean method called and the method name itself &lsqb;c&rsqb; getResult( ) (step A-22) The getResult( ) method returns the result of the method called on MessagingHomeInterface or MessagingRemoteInterface. In the case of a call on a MessagingHomelnterface, the MessagingRemoteInterface is returned as a result and in the case of a call on a MessagingRemoteInterface, the intended result is returned. In the case of an exception occurring, the exception is returned as the result value. For example, if the user had called a create( ) method on the MessagingAccountHomelnterface, the getResult( ) will return an instance of the MessagingAccountRemoteInterface object. The user can then add an event listener using the method addlistener() to this MessagingAccountRemotelnterface again and call any business method asynchronously. 2. Bean side implementation To deploy any bean in any implementation of the interface of the present invention, there are no restrictions on the bean developer. Any EJB compliant bean can be deployed when implementing the interface of the present invention. 3. API Reference—Asynchronous Interface and Class The following interfaces and class are used by the client applications: package client.messaging Interfaces public interface VandaMessagingEventListener The above interface may be implemented by the client system, i.e., the client program. There may be occasions when a bean may call another bean asynchronously. In such cases the following interface is implemented by the calling bean. This interface defines the methods that allow the client to receive and process the result. The method is: public void methodCompleted (VandaMessagingEvent resEvent) The above method is called by the client side library to inform the client program that the result of a particular call has arrived. public void exceptionOccurred(VandaMessagingEvent resEvent) The above method is called by the client side library to inform the client program that the particular call has caused an exception. Classes public class VandaMessagingEvent The above class is passed as an argument to the methodCompleted and exceptionOccurred methods of the VandaMessagingEventListener object. This class provides the calls to receive and process the result. The public method in this class is: public Object getsource( ) The above method returns the source of the event in the string from classname:methodname. public long getCallID( ) The above method returns the CallID associated with the call for which the result has arrived, i.e., the call that has caused this event. public Object getResult( ) throws Exception The above method returns the result of the method called previously (identified by CallID) or it triggers an exception in the event an exception occurred while executing the method. In the case of an exceptionOccurred in the VandaMessagingListener class, an exception may be triggered; however, an exception is generally not triggered by the methodCompletedo method. 4. Example The following code defines an Account Bean: 8 public class AccountBean implements EntityBean &lcub; public void ejbCreate(String accountId, double initialBalance, String type) &lcub; &rcub; public double getBalance ( ) &lcub; return balance; &rcub; &rcub; To create an account asynchronously using Account Bean, the create( ) method on Account Bean accepts three parameters—Name, Type of Account and Amount. The method is executed and depending on the outcome either the exceptionOccurred or the methodCompleted method is called. The following client-side code results in an asynchronous invocation on the Account Bean. public class MyClient implements 9 VandaMessagingEventListener &lcub; public myClass ( ) &lcub; InitialContext ctx &equals; new InitialContext ( ); AsyncMessagingAccountHomeInterface ref &equals; (AsyncMessagingAccountHomeInterface) ctx.lookup (“vms://AccountHomeInterface”); //Add listener to this reference ref.addListener (this); //create( ) method of Account Bean accepts three parameters Name, Type of account and Amount createID &equals; ref.create (“Michael”, “C/A”, 1000); &rcub; public void methodCompleted (VandaMessagingEvent event) &lcub; if (event.getCallID &equals;&equals; createID) &lcub; System.out.println (“record created”); // method was successful try &lcub; remoteObject &equals; (AsyncMessagingAccountRemoteInterface) event.getResult( ); &rcub; catch (Exception e) &lcub; e.printStackTrace ( ); &rcub; &rcub; &rcub; public void exceptionOccurred (VandaMessagingEvent event) &lcub; if(event.getCallID ( ) &equals;&equals; createID) &lcub;// Exception occurred&quest; System.out.println (“exception creating account”); try &lcub; remote &equals; (AsyncMessagingAccountRemoteInterface) event.getResult ( ); &rcub; catch (Exception e) &lcub; // getResult throws an error that can be handled accordingly system.out.println (“Exception Occurred;” - e.getMessage ( )) e.printStackTrace ( ); &rcub; &rcub; &rcub; public static void main (String &lsqb; &rsqb; args) &lcub; MyClass my &equals; new MyClass ( ); /* do something else */ &rcub; //private variables private long createID; private AsyncMessagingAccountRemoteInterface remoteObject; &rcub; Implementing the Interface To Achieve Asynchronous Method Invocations The present invention provides an interface that can be used with commercially available servers to achieve asynchronous method invocations at the container level. One method of implementing the interface of the present invention to achieve asynchronous method invocations entails the following steps: 1. Implement the server side communication protocol using an underlying messaging service like Oracle AQ, IBM MQ Series, JMS Implementations, etc. 2. Implement communication between client system and server using a client side library and the services of a messaging service like Oracle AQ, IBM MQ Series, JMS Implementations, etc. 3. Transparently generate asynchronous and synchronous implementations at the time of deployment of the bean in the implementation. The foregoing detailed description of the present invention is provided for the purposes of illustration and is not intended to be exhaustive or to limit the invention to the precise embodiment disclosed. Accordingly, the scope of the present invention is defined by the following claims.