Browse DevX
Sign up for e-mail newsletters from DevX


EJB and RMI: A Practical Introduction : Page 2

Since both RMI and EJB offer technology for the development, installation, and management of distributed Java applications in the enterprise, Java developers frequently ask whether one is a better option than the other for their given architectures. This article provides practical demonstrations for using RMI and EJB technologies, both individually and in tandem.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

RMI in Use
The arithmetic calculator is a simple example of the distributed application, which books and articles very frequently use. It has almost become the traditional example, and who are we to break tradition? To present an RMI system, this demonstration will carry out the actual calculations on the server side and receive the results on the client side.

A working RMI system consists of the following parts:

  • Remote services interface definitions
  • Remotes services implementation
  • Stub and Skeleton files
  • A server with remote services
  • RMI Naming service, which allows clients to locate remote services
  • Container ("supplier") of Java classes (HTTP or FTP server)
  • A client program, which requires remote services

Definition of Interfaces
For the calculator interface, the remote service offers the following methods:

public interface Calculator extends java.rmi.Remote { public long add(long a, long b) throws java.rmi.RemoteException; public long sub(long a, long b) throws java.rmi.RemoteException; public long mul(long a, long b) throws java.rmi.RemoteException; public long div(long a, long b) throws java.rmi.RemoteException; }

Each of the listed methods can throw out an exception of RemoteException class or its derivatives. Each of these methods carries out a corresponding arithmetic operation (addition, subtraction, multiplication, and division) between two numbers, a and b.

Save all the methods above as Calculator.java and compile them with the following command:

C:\j2sdk1.4.1_02\bin\javac Calculator.java

The Java SDK is placed in the default directory C:\j2sdk1.4.1_02, but if you have it in another location, specify your own path to the Java compiler.

Implement this interface for your server as well. Name the implementation class CalculatorImpl.java:

public class CalculatorImpl extends java.rmi.server.UnicastRemoteObject implements Calculator { // Implementation need to have constructor to define possibility of // RemoteException public CalculatorImpl() throws java.rmi.RemoteException { super(); } public long add(long a, long b) throws java.rmi.RemoteException { return a + b; } public long sub(long a, long b) throws java.rmi.RemoteException { return a b; } public long mul(long a, long b) throws java.rmi.RemoteException { return a * b; } public long div(long a, long b) throws java.rmi.RemoteException { return a / b; } }

Each of the methods offered in the implementation performs an arithmetic function.

As you can see, CalculatorImpl.java also extends the UnicastRemoteObject class, directly entering it into the RMI system. You don't have to extend the class to enter it into the RMI system, however. You can take advantage of the exportObject() method instead.

Since the CalculatorImpl class extends UnicastRemoteObject, you also have to define the constructor, designating from which declare it can throw out the RemoteException exception. When the constructor invokes the method super(), it carries out the constructor UnicastRemoteObject code, which communicates with RMI and initializes the remote objects.

The next step is to create the files Stub and Skeleton. You can do this with a special RMI compiler, which enables you to set the name of a class as an argument with the implementation. For example, enter the following command:

rmic CalculatorImpl

Finally, you need to write the server and client parts for the application. In this case, the following is the server-side code for your calculator:

import java.rmi.Naming; public class CalculatorServer { public CalculatorServer() { try { Calculator c = new CalculatorImpl(); Naming.rebind("rmi://localhost:1099/CalculatorService", c); } catch (Exception e) { System.out.println(e.printStackTrace()); } } public static void main(String args[]) { new CalculatorServer(); } }

As you can see, this class simply creates a copy of the Calculator interface based on its implementation (CalculatorImpl) and assigns it a name in the naming service (with the help of the Naming.rebind() method).

So the client-side code will look like this:

import java.rmi.Naming; import java.rmi.RemoteException; import java.net.MalformedURLException; import java.rmi.NotBoundException; public class CalculatorClient { public static void main(String[] args) { try { Calculator c = (Calculator) Naming.lookup("rmi://localhost/CalculatorService"); System.out.println( c.sub(8, 2) ); System.out.println( c.add(4, 5) ); System.out.println( c.mul(6, 7) ); System.out.println( c.div(8, 2) ); } catch (Exception e) { System.out.println(e.printStackTrace()); } } }

Execute Your RMI System
Now, having compiled all the classes and created the files Stub and Skeleton, you can execute your RMI system, which requires three separate consoles. In the first one, you start RMI Registry with the command rmiregistry. In the next console, start your server with the command java CalculatorServer. The server will start, load the implementation into memory, and wait for connections from clients. Lastly, start the client application with the command java CalculatorClient. If everything passes correctly, you will see the following result in the client console:

6 9 42 4

That's it. You have created and tested your own complete RMI system.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date