Java RMI is an architecture which allows distributed object computing and the development of distributed Java programs. Consider a simplified scenario with two computers A and B. Computer A hosts an object AClass with its method myAClassMethod(). With RMI, computer B can use the object AClass and invoke its method myAClassMethod(). When computer B does so, the method is computed on computer A and possibly return values are returned to computer B (via RMI). So computer A is the server, and computer B is the client.
RMI allows to use the same syntax and semantics as in non-distributed programs.
The RMI architecture defines, how objects behave, how and when exceptions can occur, how memory is managed, how parameters are passed to and returned from remote methods.
In RMI, the definition of a behaviour is separated from the implementation of that behaviour. Each of definition and implementation is allowed to run on different JVMs. In Java, interfaces define definition, and classes define implementation. The client uses the interface to connect the implementation class on the server. All communication between interface and implementation is managed by the RMI system.
![]() |
| Figure 1.1: The RMI principle |
In RMI, we have two classes that implement the same interface. The first class is the service implementation on the server, the second class is the service proxy on the client.
The client wants to request the remote service and first makes the method call to the proxy. Then the request is forwarded to the server via RMI. On the remote JVM, the request is processed and return values (if existent) returned to the client, again through the RMI system.
![]() |
| Figure 1.2: RMI interfaces |
The RMI system consists of three abstract layers:
The layers are orders as followed:
![]() |
| Figure 1.3: The RMI architecture layers |
The advantage of using a layer architecture is, that the implementation of a single layer is independent from the other layers. So one layer can be easily enhanced or replaced without affecting the rest of the system. Only the interfaces between the layers have to remain the same to maintain communication between the layers.
No we have a closer look to the single layers.
This layer lies just beneath the developer. That means that client and server programs directly communicate with elements from this layer. Here the method calls made by the client are intercepted and redirected to the remote object that provides the remote service.
The Stubs and Skeleton Layer is designed based on the Proxy Pattern as described in the book "Design Patterns" by Gamma, Helm and Johnson: One object in one context is represented by another object in another context (the proxy).
So the proxy represents the remote object on the client side. It intercepts the method calls and forwards them to the remote object on the server. In RMI, the stub class is the proxy.
The following figure illustrates the just described design. On the left side we have the server with its service object RealSubject. This object is represented on the right side (client) by the proxy. A request on the client side to the RealSubject is first intercepted and forwarded to the remote object.
![]() |
| Figure 1.4: Proxy Pattern in RMI |
The second part of the Stubs and Skeleton Layer is the skeleton class. This is a helper class generated for RMI to use. It lies on the server and communicates with the stub accross the link. The skeleton reads the parameters for the method call from the link, makes the "real" call to the service object, accepts the return values (if existent) and writes them back to the stub.
![]() |
| Figure 1.5: Skeleton-Stub communication |
The Remote Reference Layer defines and supports the invocation semantics of the RMI connection. A client that wants to access a remote object and has to do so through a remote reference. This reference is obtained through a naming service (will be discussed below). The Remote Reference Layer manages these remote references. It provides the object RemoteRef, which represents the link to the remote object. The stub object forwards the method calls by using the method RemoteRef.invoke().
In JDK 1.1 we have unicast point-to-point connections to running objects. The service object must be instantiated and exportet to the RMI system, before a client can use it.
In Java 2 SDK we also have multicast and other semantics of connections. The service object doesn't have to be running but can be activated on demand.
The RMI system uses stream-based TCP/IP network connections. The Transport Layer provides basic connectivity and firewall penetration strategies. Even if both, server and client, are on the same computer, the Transport Layer is used for all RMI communication between them.
![]() |
| Figure 1.6: The RMI Transport Layer |
On top of TCP/IP, RMI uses the Java Remote Method Protocol (JRMP). But instead of JRMP, another protocol called IIOP can be used.
RMI-IIOP is a co-production of Sun and IBM. It is based on the Internet Inter-ORB Protocol (IIOP) which was developed by the Object Management Group (OMG). This group also defined a vendor-neutral, distributed object architecture called Common Object Request Broker Architecture (CORBA). CORBA Object Request Broker (ORB) servers and clients use IIOP for communication. So with RMI-IIOP, RMI programs can inter-operate with CORBA ORBs.
To use this protocol, some modification have to be done on the source code. Several objects provided by RMI-IIOP have to be used, and the RMI compiler rmic has to be used with the switch -iiop.
Since Enterprise JavaBeans are based on RMI / RMI-IIOP, the communication with CORBA ORBs is easier when EJB components use RMI-IIOP.
Clients have to find remote services. They do so by using a naming or directory service which runs on a well known host and port number. RMI can use different directory services, e.g. the Java Naming and Directory Service (JNDI). But RMI also includes a simple service called the RMI Registry (rmiregistry), which runs on port 1099 by default.
On the host, the server program creates a remote service by creating a local object that implements the service and exporting that object to RMI. After exporting, the server registers the object in the RMI Registry under a public name. RMI creates a listening service that waits for clients to connect and request the service. The server also provides the needed class files for the client, e.g. by running a HTTP or FTP server. Missing class files can be transferred e.g. in a jar archive.
On the client side, the RMI Registry is accessed through the static class Naming. The client program uses the method Naming.lookup() to query the registry. This method accepts a URL that specifies the server host name and the name of the desired service. If needed, missing class files are downloaded from the server. The method returns a remote reference to the service object.
The URLs accepted by Naming.lookup() have the form:
rmi://<host_name>[:<name_service_port>]/<service_name>
For a working RMI system we need:
The Enterprise JavaBeans technology is an architecture for the development of transactional, 'distributed object applications'-based, server-side software. The core of this technology are the Enterprise beans. Enterprise beans, or simply beans, are server-side components. These components are distributed objects that are hosted in containers called Enterprise JavaBeans and provide provide remote services for clients distributed throughout the network.
Enterprise beans are software components that run in a special environment called EJB container. This container hosts and manages an enterprise bean. This hosting is comparable to a webserver that hosts a Java servlet, or a browser that hosts a Java applet. An enterprise bean cannot function outside its container. The EJB container manages at runtime: remote access, security, persistence, transactions, concurrency between beans, and access to and pooling of resources.
The EJB container isolates the bean from direct access by the client application. When a client invokes a method call on an enterprise bean, the container first intercepts the invocation and automatically manages persistence, transactions and security. The advantage of this encapsulation is that the developer doesn't have to care about writing that code into the bean itself, so the bean doesn't contain any of this logic.
![]() |
| Figure 2.1: The EJB container |
The containers also pool resources and manage life cycles of all beans. This reduces memory consumption and processing and leads to a higher scalability. The client application is unaware of this resource management.
An enterprise bean depends on its container for everything: for JDBC connections, for connections to other beans, for information of the identity of the caller, and for a reference to itself.
There are three types of interaction between the bean and its container. Each of them will be discussed a little more in detail now.
This is for the communication from the container to the bean. Every bean implements a subtype of the EnterpriseBean interface. This interface defines several of the so called callback methods. The container invokes these methods to activate or passivate a bean (resource management), persist its state to the database (persistence management), end a transaction, remove the bean from the method (life cycle management) etc.
This is for the communication from the bean to the container. The object EJBContext is a reference to the container. It provides methods for the bean to interact with the container. For example, it allows to request information about the bean's environment, such as the identity of its client or status of a transaction, or to obtain a remote reference to itself.
This is for the bean to access its environment. JNDI is the standard extension to the Java platform for accessing naming systems such as LDAP, NetWare, file systems etc. A bean has access to a special naming system called the Environment Naming Context (ENC). JNDI ENC allows access to JDBC connections, other enterprise beans or properties specific to that bean.
For an EJB server-side component, two interfaces and one implementation class are needed. The client uses the interfaces to interact with the bean.
The interfaces are the home interface and the remote (or business) interface. These interfaces expose the capabilities of the bean. The client has to use these interfaces to access the service provided by the bean. Both interfaces together provide all methods needed to create, update, interact with and delete the bean.
The implementation class is the bean class. It represents a business concept like a hotel clerk & customer or addressbook & contact.
![]() |
| Figure 2.2: The EJB architecture |
The home interface extends the javax.ejb.EJBHome class. This class provides life cycle methods to create, find and destroy a bean. So the home interface is used to handle the bean itself.
The remote interface extends the javax.ejb.EJBObject class. This interface represents business methods.
Both interface types will be discussed more in detail right below.
The home interface provides methods for creating, destroying and locating beans. They represent behaviour that are not specific to a single bean instance. So they have been separated from the remote interface.
We have two types of beans that provide business methods. The first type can perform tasks. This type is called session bean. For example, we have an addressbook service. The address book contains contacts. For each contact, the lastname, firstname and email address is stored. A typical task that an (electronic) addressbook has to perform is to find one or more contacts by lastname, firstname and/or email address. So we would create a session bean that performs these tasks.
The second type can represent business data stored in a database. This type of business object is called entity bean. In our example an entity bean would represent a contact. Let the following table be our (relational) database with our contacts:
| id | lastname | firstname | |
|---|---|---|---|
| 1 | Vega | Vincent | vega@pulpfiction.virtual |
| 2 | Winfield | Jules | winfield@pulpfiction.virtual |
| 3 | Wolf | Winston | wolf@pulpfiction.virtual |
Let further the class Contact be the entity bean for this database table. A single instance of Contact would then represent a row in our table. For example, the instance Contact vince represents the row with the id 1.
We just introduced the entity beans and now have a closer look to this type of beans. There are two sub-types of entity beans: Beans with Container-Managed Persistence (CMP) and with Bean-Managed Persistence (BMP).
With CMP, the container manages the persistence, which means the developer doesn't have to care about how the data is read from or written to the database. It's the container and thus the EJB server which has to manage the persistence. The developer defines variables, each corresponding to a column in the database table. These variables are called container-managed fields. These fields have to be indicated in the deployment descriptor, which is read by the EJB server. So the server knows which fields are to be filled with data from the database and which not.
With BMP, the developer has to manage database access himself. So the entity bean contains access code to the database (with JDBC). Every time a bean is created, updated or deleted, the developer has to insert, update or delete a row from the table.
Sessio beans are, as described above, used to perform tasks. Such tasks could be: Manage interactions of entity and other session beans, access resources or perform tasks on behalf of the client. Session beans are not persistent objects, the do not represent data in the database.
When creating a session bean, the developer implements the interface javax.ejb.SessionBean, which provides the methods ejbActivate() and ejbPassivate(). These methods are used by the container to send "to sleep" or to re-activate a dormant bean.
Again we have two sub-types of session beans: Stateless and stateful session beans.
Stateless beans are made up of business methods that behave like procedures. They operate only on passed through arguments on invocation, but do not maintain a business state between method invocations. So each invocation of a business method is independent from previous invocations, nothing is remembered from one invocation to the other. This leads to faster request processing, and less resources are used. Stateless beans do not use the methods ejbActivate() and ejbPassivate(), which are overridden with empty implementation. For example, a calculator service would be implemented as a stateless bean, because every invocation of a method like add or multiply is independent from previous invocations.
Stateful beans encapsulate business logic and state specific to a client. Each instance of a stateful bean is dedicated to one client, no stateful beans are shared between clients. A statful bean maintains a business (conversational) state between method invocations. It is held in memory and is not persistent. Consider a shopping cart from an online shopping system. Every customer wants to have his own articles in his cart and not any articles from other users. And all articles shall remain in the cart until the customer has removed it from the cart, bought it or ended the session. So a business state has to be held between every method invocation.
Beans can be accessed from outside on several ways. A client application is one method to use a bean. Another method is using Java Server Pages (JSP) or Java Servlets. The most commonly used method is via JSP. JSP are HTML pages with embedded Java code. First a client opens a JSP page in a browser. The server processes the page and parameters. At this point, a bean can be used to perform tasks or to access a database. After that, the results are sent back to the browser (in HTML format).
This report is based on following documents: