In this chapter we've implemented the simple distributed compute engine using both CORBA and RMI, and we've seen many similarities between the two in terms of functionality. There are also some critical differences between the two technologies. In order for you to understand which distributed object scheme is right for whatever system you're facing, it's important to spell out these differences.
As we mentioned before, RMI is a Java-centric distributed object system. The only way currently to integrate code written in other languages into a RMI system is to use the Java native-code interface to link a remote object implementation in Java to C or C++ code. This is a possibility, but definitely not something for the faint of heart. The native-code interface in Java is complicated, and can quickly lead to fragile or difficult-to-maintain code. CORBA, on the other hand, is designed to be language-independent. Object interfaces are specified in a language that is independent of the actual implementation language. This interface description can then be compiled into whatever implementation language suits the job and the environment.
This distinction is really at the heart of the split between the two technologies. RMI, as a Java-centric system, inherits all of the benefits of Java. An RMI system is immediately cross-platform; any subsystem of the distributed system can be relocated to any host that has a Java virtual machine handy. Also, the virtual machine architecture of Java allows us to do some rather interesting things in an RMI system that just aren't possible in CORBA. For example, using RMI and the object serialization in the java.io package, we can implement an agent-based system where clients subclass and specialize an Agent interface, set the operating parameter values for the agent, and then send the object in its entirety to a remote "sandbox" server, where the object will act in our name to negotiate on some issue (airline ticket prices, stocks and bonds, order-fulfillment schedules, etc.). The remote server only knows that each agent has to implement an agreed-upon interface, but doesn't know anything about how each agent is implemented, even though the agent is running on the server itself. In CORBA, objects can never really leave their implementation hosts; they can only roam the network in the virtual sense, sending stub references to themselves and to clients. We don't have the option of offloading an object from one host to another.
However, CORBA doesn't require a commitment to a single implementation language. We can pick and choose how different elements of a distributed system are implemented based on the issues at hand. Legacy systems may dictate our implementation language in some cases (large COBOL systems like to be spoken to in COBOL, for example). Performance may be an issue in other cases. Heavy computational tasks like computational fluid dynamics and finite-element modeling are best written in languages that can be compiled down to native hardware instructions, like C and C++. The Java virtual machine architecture is a disadvantage here, since an additional interpretation layer is added to the processing of instructions. The Java just-in-time compilers (JIT) are capable of generating native instructions from Java bytecodes, but there is still an additional piece of overhead in running each piece of Java code. If we know that migrating system elements around the network is not necessary, then natively compiled Java code can be permanently installed, but by doing this we're sacrificing the critical "run everywhere" aspect of Java.
If we're using CORBA in these cases, we can take IDL interface definitions for our objects, compile them into COBOL, C, C++, or whatever languages we need at the various nodes in our distributed system. As long as the ORB implementations that we use at each node support a standard inter-ORB protocol like IIOP, the various CORBA objects implemented in various languages can interact with each other just fine.
In addition to this core distinction between CORBA and RMI, there are other differences to keep in mind:
Relatively speaking, RMI can be easier to master, especially for experienced Java programmers, than CORBA. CORBA is a rich, extensive family of standards and interfaces, and delving into the details of these interfaces is sometimes overkill for the task at hand.
CORBA is a more mature standard than RMI, and has had time to gain richer implementations. The CORBA standard is a fairly comprehensive one in terms of distributed objects, and there are CORBA implementations out there that provide many more services and distribution options than RMI or Java. The CORBA Services specifications, for example, include comprehensive high-level interfaces for naming, security, and transaction services (see Appendix B, "CORBA Services").
Various low-level technical details about the two schemes may be seen as advantages or disadvantages to you as a developer: the fact that RMI imposes additional throws clauses in your remote interface is one that we've already mentioned, and CORBA's peer-to-peer ORB communication model as opposed to RMI's server-centric model may be another.
So which is better, CORBA or RMI? Basically, it depends. If you're looking at a system that you're building from scratch, with no hooks to legacy systems and fairly mainstream requirements in terms of performance and other language features, then RMI may be the most effective and efficient tool for you to use. On the other hand, if you're linking your distributed system to legacy services implemented in other languages, or if there is the possibility that subsystems of your application will need to migrate to other languages in the future, or if your system depends strongly on services that are available in CORBA and not in RMI, or if critical subsystems have highly-specialized requirements that Java can't meet, then CORBA may be your best bet.
Copyright © 2001 O'Reilly & Associates. All rights reserved.