===== Simple Java-RMI Example ===== First of all, let's create an interaction diagram that demonstrates how the Client and RObject communicate with each other through RegisterService: sequenceDiagram participant C as Client participant RS as RegisterService participant RO as RObject participant RMI as RMI Registry RS->>RMI: Register RObject RMI-->>RS: RObject Registered C->>RMI: Lookup RObjectServer RMI-->>C: Return RObject C->>RO: primitiveArg(2012) RO-->>C: Acknowledge C->>RO: argumentByValue(2012) RO-->>C: Acknowledge This diagram illustrates the steps of the process: RegisterService registers the RObject in the RMI Registry, the Client queries the remote object, then uses its functions. Now let's see what this system looks like in a structure diagram, which shows the components and their relationships: graph TD subgraph "RMI Registry" RO[RObject Interface] end subgraph "Server Side" ROS[RObjectImpl] -- Implements --> RO end subgraph "Client Side" C[Client] -- Uses --> RO end RegisterService -- Registers --> RO C -- Looks up --> RO C -- Calls methods on --> ROS The structure diagram clearly depicts the different parts of the system and the relationships between them: The Server Side section contains the RObjectImpl implementation, which implements the RObject interface. The RMI Registry registers the interface, allowing the Client Side Client to find and use it. The Client calls the methods of the remote object (ROS), illustrating the two main operations: passing a primitive and passing by value. **Implementation:** Install Gradle from here: https://gradle.org/releases/ Add the //bin// directory to the //PATH//. The complete source code is available here: git clone https://github.com/knehez/isi.git cd java_rmi Open two terminals, in one of them: gradle runRegisterService In the other one: gradle run The program in detail: 1.) Define the **RObject** interfaces, both implement the Remote interface package org.ait; import java.rmi.*; public interface RObject extends Remote { // simple argument passing void primitiveArg(int num) throws RemoteException; // pass by value argument void argumentByValue(Integer num) throws RemoteException; } 2.) Implement the code for remote objects package org.ait; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class RObjectImpl extends UnicastRemoteObject implements RObject { private static final long serialVersionUID = 6350331764929058681L; public RObjectImpl() throws RemoteException { } @Override public void primitiveArg(int num) throws RemoteException { System.out.println(num); } @Override public void argumentByValue(Integer num) throws RemoteException { System.out.println(num); } } 3.) Start the RMI registry. This is a **Java JDK** component, to start it you should be in the created project's **/bin** directory. 4.) Create an instance of the remote object and bind it to the registry package org.ait; import java.rmi.Naming; public class RegisterService { /** * @param args */ public static void main(String[] args) { try { java.rmi.registry.LocateRegistry.createRegistry(1099); RObject robj = new RObjectImpl(); Naming.rebind("rmi://localhost:1099/RObjectServer", robj); System.out.println("Registered..."); } catch (Exception e) { e.printStackTrace(); } } } Start the RegisterService, it can only register if the rmiregistry is running. 5.) Use the remote object Start the following code. package org.ait; import java.rmi.Naming; public class Client { public static void main(String[] args) { try { // Retrieving the remote object from the registry RObject robj = (RObject) Naming.lookup("rmi://localhost:1099/RObjectServer"); // Simple argument robj.primitiveArg(2012); // Serialized argument robj.argumentByValue(new Integer(2012)); } catch (Exception e) { e.printStackTrace(); ; } } }