Unit 5 · 6 teaching hours · 39 min read
Remote Method Invocation and CORBA
What the syllabus asks for 5
- Distributed objects and RMI
- Parameters: by value or by reference
- A complete RMI program
- CORBA
- Seeing the ideas: stubs, copies, wire bytes and failures
With sockets you design a message format, write the parser, and send bytes.
With Remote Method Invocation (RMI) you simply call a method on an object that lives in another JVM, and Java handles the connection, the marshalling of arguments, the transfer and the unmarshalling of the result.
The call looks like a local call; what it hides is exactly what makes distributed programming hard: partial failure, latency and the fact that arguments are copied while remote objects are referenced.
This unit runs a real RMI registry, server and client in one program and then compares RMI with CORBA, its language-neutral cousin.
- The RMI architecture: remote interface, implementation, stub, registry, client.
- Parameter passing: by value (serialization) versus by remote reference.
- Writing, running and deploying an RMI application; exceptions.
- CORBA: ORB, IDL, IIOP; RMI versus CORBA.
5.1 Distributed objects and RMI
A distributed object system lets a client in one JVM invoke methods of an object in another, on the same machine or across a network. RMI is Java's native technology for it (package java.rmi), designed around three ideas:
- the remote interface declares what a client may call (it extends
java.rmi.Remote, and every method throwsRemoteException); - the implementation (the server object) does the work (usually extends
UnicastRemoteObject, which exports the object so it can receive calls); - a stub (a client-side proxy implementing the same interface) turns each method call into a network request, marshalls (serializes) the arguments, waits for the reply and unmarshalls the result or exception. In modern Java the stub is a dynamic proxy generated automatically; older versions required the
rmiccompiler, and the server-side skeleton is no longer needed.
Architecture
| Layer | Role |
|---|---|
| Application | client and server code using the remote interface |
| Stub and skeleton (proxy layer) | intercept calls and marshal/unmarshal |
| Remote reference layer | locates the object, manages the connection semantics |
| Transport layer | TCP connections (Java Remote Method Protocol, JRMP) |
The RMI registry
The client needs a first reference to a remote object.
The RMI registry is a simple naming service: the server binds a name to the stub (registry.rebind("Calculator", stub)), and the client looks it up (registry.lookup("Calculator")) and receives a stub.
The registry listens on port 1099 by default and can be started inside the server with LocateRegistry.createRegistry(port) or as a separate program rmiregistry. Names can be addressed as URLs: rmi://host:1099/Calculator.
5.2 Parameters: by value or by reference
- Primitives and serializable objects are passed by value: a copy is made by serialization, so changes the server makes to its copy are not seen by the client, and vice versa. The class must implement
Serializableand, if the client lacks it, the class file must be made available (a codebase), which is the reason Java now restricts remote class loading. - Remote objects (those implementing
Remote) are passed by reference: the receiver gets a stub for the original, and calls through it run on the object's home JVM. - Non-serializable, non-remote arguments cause
java.rmi.MarshalException(caused byNotSerializableException).
5.3 A complete RMI program
The following single file defines a remote interface, an implementation with state, starts a registry on a fixed local port, binds the object, looks it up like a client would and calls it.
It demonstrates a method with primitives, a pass-by-value object (Point), a remote counter whose state lives on the server, and an unbound lookup.
import java.io.Serializable;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.UnicastRemoteObject;
public class RmiDemo {
public interface Calculator extends Remote {
int add(int a, int b) throws RemoteException;
Point translate(Point p, int dx, int dy) throws RemoteException;
int increment() throws RemoteException;
}
public static class Point implements Serializable {
private static final long serialVersionUID = 1L;
public int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
public String toString() { return "(" + x + "," + y + ")"; }
}
public static class CalculatorImpl extends UnicastRemoteObject implements Calculator {
private int counter = 0;
public CalculatorImpl() throws RemoteException { super(); }
public int add(int a, int b) { return a + b; }
public Point translate(Point p, int dx, int dy) { p.x += dx; p.y += dy; return new Point(p.x, p.y); }
public synchronized int increment() { return ++counter; }
}
public static void main(String[] args) throws Exception {
System.setProperty("java.rmi.server.hostname", "127.0.0.1");
Registry registry = LocateRegistry.createRegistry(51234);
registry.rebind("Calculator", new CalculatorImpl());
System.out.println("bound names: " + String.join(",", registry.list()));
Registry clientView = LocateRegistry.getRegistry("127.0.0.1", 51234);
Calculator calc = (Calculator) clientView.lookup("Calculator");
System.out.println("stub is a proxy, not the implementation: " + !(calc instanceof CalculatorImpl));
System.out.println("add(19, 23) = " + calc.add(19, 23));
Point mine = new Point(1, 2);
Point moved = calc.translate(mine, 10, 20);
System.out.println("returned copy = " + moved + ", my original is still " + mine + " (passed by value)");
System.out.println("remote counter: " + calc.increment() + ", " + calc.increment() + ", " + calc.increment());
Calculator second = (Calculator) clientView.lookup("Calculator");
System.out.println("a second client sees the same server object: " + second.increment());
try { clientView.lookup("NoSuchService"); }
catch (NotBoundException e) { System.out.println("NotBoundException: " + e.getMessage()); }
System.exit(0);
}
}
bound names: Calculator
stub is a proxy, not the implementation: true
add(19, 23) = 42
returned copy = (11,22), my original is still (1,2) (passed by value)
remote counter: 1, 2, 3
a second client sees the same server object: 4
NotBoundException: NoSuchService
The server's translate method moved its copy of the point; the caller's object was untouched, so serialization means pass by value.
The counter lives on the server: three calls give 1, 2, 3, and a second lookup returns another stub for the same server object, so its call returns 4.
Writing and running RMI in practice
- Write the remote interface (extends
Remote, methodsthrows RemoteException). - Write the implementation (extends
UnicastRemoteObject, or callUnicastRemoteObject.exportObject). - Write the server: create or locate the registry,
rebindthe object. - Write the client:
LocateRegistry.getRegistry(host, port),lookup, call methods. - Compile; start
rmiregistry(or let the server create it); start the server, then the client. Firewalls must allow the registry port and the object's export port (set it explicitly withUnicastRemoteObject.exportObject(obj, port)), and the server'sjava.rmi.server.hostnamemust be an address the client can reach (the demo sets 127.0.0.1; a wrong value is the classic cause of connection hangs).
Exceptions and failure
Every remote call can fail in ways a local call cannot, which is why every method declares RemoteException: ConnectException (server unreachable), NoSuchObjectException (object no longer exported), MarshalException/UnmarshalException (serialization problems), ServerException (the remote method itself threw).
The caller must decide whether to retry, and a retry of a non-idempotent call (like increment) may run it twice. This is the "partial failure" problem of distributed systems.
RMI features and limits
- Callbacks: a client can pass a remote object (its own listener) to the server, which then calls it back; each side becomes both client and server.
- Distributed garbage collection via leases.
- Security: RMI used to download code from remote codebases; since Java 8u121 (and in 17) remote class loading is disabled by default and a serialization filter (
ObjectInputFilter) should be set to avoid deserialization attacks. - Java only: both sides must be Java (the price of being native and simple).
- Alternatives today: REST/JSON over HTTP, gRPC, message queues.
5.4 CORBA
CORBA (Common Object Request Broker Architecture, defined by the Object Management Group in 1991) gives distributed objects across languages and platforms: a C++ client can call a Java object, a Python object or a COBOL object.
| CORBA concept | Meaning |
|---|---|
| ORB (Object Request Broker) | the middleware that locates objects and carries requests |
| IDL (Interface Definition Language) | language-neutral description of interfaces; a compiler generates stubs and skeletons for each language |
| IIOP (Internet Inter-ORB Protocol) | the standard wire protocol over TCP |
| Stub / skeleton | client proxy / server-side dispatcher generated from IDL |
| Naming Service | like the RMI registry: names → object references |
| POA (Portable Object Adapter) | server-side object management |
An interface in IDL looks like Java without bodies:
module college {
struct Student { string name; long marks; };
interface Registrar {
Student find(in long id);
void enroll(in Student s);
readonly attribute long count;
};
};
Steps: write the IDL; compile with an IDL compiler to produce stubs and skeletons; implement the servant; register it with the ORB and the Naming Service; the client resolves the name, narrows the reference to the interface type and calls it.
CORBA support was deprecated in Java 9 and removed from the JDK in Java 11, so the IDL example above is shown but not compiled here (it needs a third-party ORB such as JacORB).
CORBA is still met in older telecom, banking and defence systems and in examination syllabi, but new systems use REST, gRPC or messaging.
RMI versus CORBA
| Aspect | RMI | CORBA |
|---|---|---|
| Languages | Java only | many (C++, Java, Python, …) |
| Interface definition | a Java interface | IDL |
| Parameter passing | objects by value (serialization) or remote reference | objects by reference or by value via IDL types |
| Protocol | JRMP (and RMI-IIOP) | IIOP |
| Complexity | low | high |
| Extra services | little | naming, events, transactions, security |
| Status | still in the JDK | removed from the JDK (Java 11) |
RMI-IIOP let RMI code speak IIOP to interoperate with CORBA. Today the same needs are met by web services: SOAP (XML, WSDL) and REST (HTTP, JSON), and by gRPC (HTTP/2, Protocol Buffers, with an IDL much like CORBA's).
5.5 Seeing the ideas: stubs, copies, wire bytes and failures
A remote call is easier to understand when you can picture it and measure it.
Plate 5.1 gives four everyday pictures: a remote control for the stub, a telephone and its directory for the registry, a card catalogue for names that lead to objects, and a pneumatic tube for the transport.
Plate 5.2 shows a photocopier for pass by value, standard containers for serialization, an interpreters' booth for the ORB and the Rosetta Stone for IDL. Plate 5.3 shows why distance matters: antennas that talk to a rover on Mars.
Figures 5.1 to 5.9 then use numbers from one real run of Java 17 (a registry, a server object and a client in one program, with a socket wrapper that counted every byte), and Figures 5.10 to 5.12 turn to CORBA and the choice of technology today.










5.5.1 Eight uses of remote-object ideas in Nepal
RMI itself is now mostly met in older Java systems and in examinations, but every idea in this unit (a stub, a name lookup, a copy against a reference, a thread per call, a retry) lives on in the services that Nepali students use every day.
Each point below says where the idea appears.
- Branch banking and core banking. A teller screen in a branch does not hold the accounts; it calls services in the bank's data centre, and each call crosses a network (Figure 5.1). A call that took 1 nanosecond locally takes tens of microseconds even on one machine (Figure 5.4), and much more over a real link. Good designs therefore send one coarse request, such as a whole deposit slip, and not many tiny calls.
- Payment gateways such as ConnectIPS and Fonepay. When a payment request is sent and the answer is lost, the wallet cannot know whether the money moved. A blind retry could debit a customer twice (Figure 5.9). Real payment services avoid this with a unique request number that the server remembers, so a repeated request is recognised and answered again, not run again.
- The Nagarik App and government back ends. The app talks to servers of several offices, and many of those servers are written in different languages. For this reason such services use REST and JSON over HTTPS, not Java RMI, which only speaks Java (Figure 5.12). The ideas are still the same: a name or URL is looked up, arguments are copied into a message, and every call can fail.
- Tribhuvan University results and EMIS portals. On result day thousands of students ask the server at the same moment. The server runs each request in its own thread, exactly as an RMI server does (Figure 5.7), so the shared parts, such as a hit counter, must be thread-safe. A synchronized counter gave the right numbers in the unit's run; an unprotected one would lose counts, as Unit 1 showed.
- Electricity bill and utility counters. A counter in a ward office asks the central billing server for the dues of a customer number. The request and the reply are copies of small objects (Figure 5.5), and the counter must show a clear error when the server is unreachable, as ConnectException does (Figure 5.8). The screen must never freeze while it waits, so the call runs in a background thread with a timeout.
- Hospital and laboratory systems. A doctor's computer sends a test request and later receives the result. The request can carry a callback object, so the laboratory calls the doctor's program when the result is ready (Figure 5.6), instead of the program asking again and again. The patient record travels by value, a copy, so the lab cannot change the original by mistake.
- Telecom and equipment management. Telecom companies run equipment from several makers, and older management systems describe each device in IDL and talk through CORBA and IIOP (Figures 5.10 and 5.11). A graduate who joins such a company may have to maintain this code, even though new systems choose gRPC or REST. Knowing the stub, skeleton and ORB makes the old code readable.
- BCA projects and college labs. A common project is a chat or an attendance system in which clients call a server object and the server calls back each client. The client must find the server's address (Figure 5.2), and a wrong java.rmi.server.hostname is the classic reason for a connection that hangs. Testing on the loopback address with a fixed registry port makes the project easy to run in a lab without a network.
Formula and fact sheet
- Remote interface extends
Remote; methodsthrows RemoteException; implementation extendsUnicastRemoteObject. - Server:
LocateRegistry.createRegistry(port)+rebind(name, obj); client:getRegistry(host, port)+lookup(name). Default registry port 1099. - Parameters: serializable → by value (copy);
Remoteobjects → by reference (stub). - Every remote call can fail: handle
RemoteException; retries may repeat non-idempotent operations. - CORBA: ORB + IDL + IIOP; removed from the JDK in Java 11.
Chapter summary
- RMI lets a client call methods on an object in another JVM through a stub; a registry maps names to stubs; the transport is TCP (JRMP).
- Serializable arguments are copied (so the server cannot change the caller's object), remote objects are referenced; the object's state stays on the server.
- Distribution adds failure modes, so remote methods declare
RemoteExceptionand callers must handle partial failure. - CORBA offers language-neutral distributed objects with IDL, an ORB and IIOP but is obsolete in the JDK; REST and gRPC are today's choices.
Practice
- Explain the RMI architecture: stub, remote reference layer, transport and registry.
- List the steps to write an RMI application.
- What must a remote interface look like? Why does every method throw
RemoteException? - Distinguish pass by value and pass by reference in RMI with an example from the program above.
- What is the RMI registry, on which port does it listen by default, and what do
bind,rebindandlookupdo? - Why might a retry after a
RemoteExceptionbe dangerous? - Define CORBA, ORB, IDL and IIOP.
- Compare RMI and CORBA in five points.
- Write the IDL for an interface with one method
add(in long a, in long b)returning a long. - Name two modern alternatives to RMI/CORBA and what they use instead of IDL.
Answers and worked solutions
1. The client calls a method on the stub; the stub marshals the arguments and sends them through the remote reference layer and the TCP transport to the server's JVM, which unmarshals them and invokes the real object; the result returns the same way. The registry gives the client its first stub by name.
2. Write the remote interface; write the implementation; write the server that creates or locates the registry and binds the object; write the client that looks it up; compile and run registry, server and client.
3. public interface Calculator extends Remote { int add(int a, int b) throws RemoteException; }. Network failure is always possible, so the interface forces callers to deal with RemoteException.
4. Point is Serializable: translate(mine, 10, 20) received a copy, changed it and returned a new object; mine still printed (1,2). The Calculator is a Remote: the client holds a stub, and increments change the one server object (1, 2, 3, then 4 from a second client).
5. A simple naming service that maps names to remote stubs; default port 1099. bind adds a binding (fails if it exists), rebind adds or replaces, lookup returns the stub for a name.
6. The first call may have executed on the server even though the reply was lost, so repeating a non-idempotent call such as increment or "transfer money" runs it twice.
7. CORBA: language-neutral distributed object standard of the OMG. ORB: the broker that routes requests. IDL: the interface description language. IIOP: the standard TCP protocol between ORBs.
8. RMI is Java-only, uses Java interfaces, is simpler, uses JRMP and is still in the JDK; CORBA is multi-language, uses IDL, is complex, uses IIOP, offers many services and was removed from the JDK in 11.
9. interface Calculator { long add(in long a, in long b); };
10. REST/JSON over HTTP (resources and URLs, description via OpenAPI) and gRPC (HTTP/2 with Protocol Buffers, whose .proto files play the role of IDL).
Model answers for Unit 5
Q1. Explain the architecture of Java RMI and how a remote call travels from client to server. (10 marks)
Introduction. Remote Method Invocation lets a program in one JVM call a method of an object that lives in another JVM as if it were a local object. The call looks ordinary, but a stub, a transport and a registry do the hidden work (Fig. 5.1).
The parts.
- Remote interface. It extends
java.rmi.Remote, and every method declaresthrows RemoteException. It is the contract the client sees. - Implementation. The server class implements the interface, usually by extending
UnicastRemoteObject, which exports the object on a TCP port. In the run, the object was exported on port 33225, chosen by the system. - Stub. The client holds a stub, a proxy that implements the same interface. In Java 17 it is a dynamic proxy of class
jdk.proxy1.$Proxy0, so normicis needed. - Remote reference layer. It marshals the arguments into bytes and unmarshals the result.
- Transport. A TCP connection carries the Java Remote Method Protocol; the first bytes were
4a 52 4d 49 00 02 4b, the letters JRMI, version 2 and the stream code (Fig. 5.3). - Registry. A naming service, on port 1099 by default (51234 in the run), maps a name such as
Calcto a stub. The server callsrebind, and the client callslookup.
Path of one call. The client calls calc.add(19, 23) on the stub. The stub and the reference layer marshal the two ints and send a 50-byte request.
The server's transport receives it, the dispatch layer unmarshals the arguments and calls Impl.add, and the answer 42 returns in 27 bytes.
The lookup before it moved 559 bytes out and 624 bytes in over two connections, and the 5,000 calls that followed opened no new socket, because connections are reused (Fig. 5.2).
| Layer | Client side | Server side |
|---|---|---|
| Application | calls the interface | real object |
| Proxy | stub | dispatch (skeleton role) |
| Reference | marshals arguments | marshals result |
| Transport | TCP socket | ServerSocket |
Conclusion. RMI hides the network behind a method call, but it cannot hide its cost or its failures.
Even on one machine the call took 53.0 microseconds against 1 nanosecond for a local call, so a designer treats a remote call as an expensive operation that can fail (Fig. 5.4).
Q2. Write the steps of a minimal RMI application with the key code. (5 marks)
An RMI application needs five steps, and the same steps were used in the unit's program.
- Write the remote interface. It extends
Remote, and each method throwsRemoteException. - Write the implementation. It extends
UnicastRemoteObjectand has a constructor that throwsRemoteException. - Write the server. It creates or finds the registry and binds the object.
- Write the client. It gets the registry, looks up the name and calls the stub.
- Run. Start the registry and server first, then the client. Set
java.rmi.server.hostnameto an address the client can reach, and allow the registry port and the object's port through the firewall.
public interface Calculator extends Remote {
int add(int a, int b) throws RemoteException;
}
public class CalculatorImpl extends UnicastRemoteObject implements Calculator {
public CalculatorImpl() throws RemoteException { super(); }
public int add(int a, int b) { return a + b; }
}
// server
Registry reg = LocateRegistry.createRegistry(51234);
reg.rebind("Calc", new CalculatorImpl());
// client
Registry r = LocateRegistry.getRegistry("127.0.0.1", 51234);
Calculator c = (Calculator) r.lookup("Calc");
System.out.println(c.add(19, 23)); // 42
In the real run this printed 42 after a 50-byte request and a 27-byte reply (Fig. 5.2).
Notice that the client code never mentions sockets, bytes or ports of the object: the stub finds the object's port inside the reference that the registry returned.
The server must also keep a reference to the registry or the object, otherwise the object may be garbage collected and later calls fail with NoSuchObjectException.
A lookup of a name that was never bound threw NotBoundException, and a second bind of a used name threw AlreadyBoundException; rebind replaces silently, which is why servers usually use it (Fig. 5.8).
Q3. Distinguish pass by value and pass by reference in RMI with the experiment of the unit. (5 marks)
RMI passes an argument in one of two ways, according to its type (Fig. 5.6).
Pass by value. A primitive or a Serializable object is turned into bytes and rebuilt at the other end, so the server works on a copy.
In the experiment a CopyCounter was sent to the server, which added 100 and returned 100, but the client's own object still held 0.
The copy of this small object cost 47 bytes, but an int[1000] costs 4,027 bytes and an ArrayList of 1,000 Integer objects 10,125 bytes, so a big argument is expensive every time it is sent (Fig. 5.5).
Pass by reference. An object that implements Remote is not copied. The receiver gets a stub, which is only 282 bytes however large the object is.
In the experiment a RefCounter was passed, and the server called bump() three times; each call ran in the client's JVM, in a thread named RMI TCP Connection, and the client's counter became 3.
The server's argument was an instance of a proxy class, not of the real class.
| Point | By value | By reference |
|---|---|---|
| Type needed | Serializable |
Remote |
| Where the work runs | at the receiver, on a copy | at the home JVM |
| Cost | size of the object | 282-byte stub, but every call crosses the network |
An argument that is neither type fails with MarshalException, caused by NotSerializableException.
Q4. How is a remote call different from a local call? Discuss cost, concurrency and failure with a diagram reference. (10 marks)
Introduction. RMI makes a remote call look like a local call, but the two differ in speed, in how arguments are passed, in concurrency and, above all, in the ways they can fail. A programmer who forgets this writes slow and fragile systems.
Differences.
- Cost. A local
addtook 1.01 nanoseconds in the run, and the same call through RMI took 53.0 microseconds, about 52,000 times longer, on one machine with no real network (Fig. 5.4). A thousand fine calls would cost about 53 milliseconds. - Payload. A call needs 42 bytes of overhead, and each int sent costs 4 bytes more (Fig. 5.3). A 100,000-element array took 5,712 microseconds, about 70 MB per second.
- Parameters. Serializable arguments are copied, and Remote arguments are passed as stubs (Fig. 5.6). A local call shares the object itself.
- Concurrency. The server runs each call in its own thread. Four clients calling a 200 ms method finished in 203 ms, against 802 ms one by one (Fig. 5.7), so the remote object must be thread-safe.
- Failure. A local call either runs or throws. A remote call may fail before, during or after the work, and the caller cannot tell which. The exceptions of the run were
ConnectException,NoSuchObjectException,MarshalException,NotBoundExceptionandAlreadyBoundException(Fig. 5.8). - Retry. If the reply is lost, repeating the call may repeat the work. In the run a lost reply and one retry made the server counter 2 although the client had asked for one increment (Fig. 5.9).
| Aspect | Local call | Remote call |
|---|---|---|
| Time | about 1 ns | about 53 us on loopback |
| Arguments | shared | copied or stubbed |
| Failure | exception only | silent loss possible |
| Retry | harmless | may repeat the work |
Remedies. Use few coarse methods, set timeouts, make operations idempotent (such as setBalance(800)), send a request number that the server remembers, or use a transaction.
Conclusion. A remote call is a network message in disguise. The wise rule is to design the interface around that fact: coarse, thread-safe, and safe to repeat.
Q5. What is the RMI registry? Explain bind, rebind, lookup and the default port. (5 marks)
The RMI registry is a simple naming service that stores bindings from names to remote stubs. A client needs a first stub to start with, and the registry gives it by name, like a telephone directory that gives a number for a name (Plate 5.1).
- Starting it. The server calls
LocateRegistry.createRegistry(port), or an operator runs thermiregistrytool. The default port is 1099; the run used 51234. bind(name, stub). It adds a binding and throwsAlreadyBoundExceptionif the name exists.rebind(name, stub). It adds a binding or replaces an old one without complaint.lookup(name). It returns the stub for the name, or throwsNotBoundExceptionfor an unknown name (the run:NotBoundException: Nope).- Names as URLs. A name may be written as
rmi://host:1099/Calc.
In the run, getRegistry and lookup moved 559 bytes out and 624 bytes in, and used two connections: one to the registry port and one to the object's own port (Fig. 5.2).
If no registry listens on the port, the client gets a ConnectException caused by Connection refused. The registry stores only stubs, never the objects, so the objects remain on the server.
Q6. Name and explain the exceptions an RMI program must handle. (5 marks)
Every remote method declares RemoteException because the network can fail. The run of the unit produced seven different failures (Fig. 5.8).
ConnectException. The client could not reach the registry or the server. The lookup at port 51999 failed with the causeConnection refused.NoSuchObjectException. The object is no longer exported, for instance after the server unexported it; the message wasno such object in table.MarshalExceptionandUnmarshalException. An argument or result could not be turned into bytes. Passing a plainObjectcaused aMarshalExceptionwith the causeNotSerializableException.NotBoundExceptionandAlreadyBoundException. These are naming errors from the registry.- Exceptions of the method itself. A declared exception such as
InsufficientFunds(balance 500 less than 800) and a runtime exception such asIllegalArgumentExceptionreach the client unchanged, so business errors can be handled in the normal way.
A caller should catch RemoteException separately from business exceptions, and it should decide whether a retry is safe. A retry of a non-idempotent call such as increment() may run it twice, as the counter of 2 showed (Fig. 5.9).
Timeouts and clear messages to the user complete the handling.
Q7. Explain the architecture of CORBA and compare it with RMI. (10 marks)
Introduction. The Common Object Request Broker Architecture (CORBA) was defined by the Object Management Group in 1991 to let objects written in different languages and running on different machines call each other.
It was removed from the JDK in Java 11, but it is still in syllabi and in older telecom, banking and defence systems.
Architecture (Fig. 5.10).
- IDL. The Interface Definition Language describes interfaces in a language-neutral way. An IDL compiler reads
college.idland writes the client stub and the server skeleton in the chosen languages. - Stub and skeleton. The client calls the stub, and the skeleton passes the request to the servant.
- ORB. The Object Request Broker finds the object and carries the request and reply.
- IIOP. The Internet Inter-ORB Protocol, over TCP, is the standard wire format. Its messages start with a 12-byte GIOP header (Fig. 5.11).
- POA. The Portable Object Adapter manages servants on the server.
- Naming Service. It plays the role of the RMI registry.
- Type mapping. IDL
longbecomes Javaint,stringbecomesString, astructbecomes a class and asequencean array.
Comparison.
| Aspect | RMI | CORBA |
|---|---|---|
| Languages | Java only | many |
| Contract | a Java interface | IDL file |
| Wire protocol | JRMP (7-byte stream header) | IIOP (12-byte GIOP header) |
| Complexity | low | high |
| Services | few | naming, events, transactions, security |
| Status | in the JDK | removed in Java 11 |
Today. Needs once met by CORBA are now met by REST and JSON, by gRPC, whose .proto file replaces IDL, and by message queues (Fig. 5.12).
Example. In a bank, a Java teller program may call a COBOL account object through CORBA: both sides compile the same Account interface from IDL, the Java side gets an Account interface plus AccountHelper and AccountHolder classes, and the COBOL side gets its own skeleton.
Neither team needs to know how the other stores its data, and a change of the contract means a change of the IDL file and a recompile of both sides.
Conclusion. CORBA gives language freedom at the price of complexity, and RMI gives simplicity at the price of being Java-only. New systems choose REST or gRPC, and CORBA is maintained but rarely started.
Q8. What is a callback in RMI, and why must remote objects be thread-safe? (5 marks)
A callback is a call from the server back to the client. The client creates a remote object of its own, a listener, and passes it to the server as an argument.
Because the listener implements Remote, the server receives a stub and not a copy, and each call through it runs in the client's JVM.
In the run the server received an object of a proxy class that was not an instance of the real listener class, and three ping calls arrived in a thread named RMI TCP Connection (Fig. 5.6).
Callbacks suit events such as a lab result being ready or a new chat message, because the client does not have to ask again and again. Each side now acts as both client and server, so both need an open port and a reachable host name.
Thread safety. The server runs every call in its own thread. Four clients calling a 200 ms method finished in 203 ms, not 802 ms, so the calls overlapped (Fig. 5.7).
If two threads change one field together, an update can be lost, as shown in Unit 1. The shared counter therefore used synchronized, and similar fields need synchronized, a lock or an atomic class.
Q9. Which technology would you choose today for a remote call, and why? (5 marks)
The choice depends on four questions, as the decision chart shows (Fig. 5.12).
- Can the caller move on without waiting? Then use a message queue such as Kafka or RabbitMQ. It decouples the two sides in time, and a lost reply does not stall the caller.
- Are all callers Java and in one team? RMI works, but it is Java only, needs extra ports and ties the two sides to the same classes. An old system may keep it, while a new one should still prefer gRPC.
- Are the calls typed, fast and internal? Choose gRPC. The
.protofile serves as the contract, as IDL did, and HTTP/2 carries compact binary messages. - Must any language or a browser call it? Choose REST with JSON over HTTPS. This is the choice of the Nagarik App style of service, because every language has an HTTP client.
CORBA is chosen only to maintain an old system that already depends on an ORB, usually with a gateway in front of it.
Whatever the choice, the lessons of this unit apply: calls are slow compared with local calls (53 microseconds against 1 nanosecond), arguments are copies, failures are silent, and a retry must be safe.