JavaEnterprise JavaUsing Java IDL

Using Java IDL

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.


The Java 2 (formerly JDK 1.2) platform supports CORBA through Java IDL (Interface Definition Language) [1]. CORBA is an industry-standard middleware protocol that helps developers build distributed applications. The addition of CORBA as a standard component greatly enhances Java support for these cutting-edge apps.

CORBA differs from other object-oriented middleware such as RMI and DCOM by being both language and platform neutral — e.g., Windows clients written in Java can interact with remote C++ objects running on a Unix server as if they were local objects. CORBA hides the complexity of a heterogeneous network behind a clean object-oriented interface.

Several Java implementations of CORBA are available on the market. These implementations are typically more complete than Java IDL. In particular, they include powerful CORBAServices such as transaction management. Java IDL is a minimalist implementation of CORBA, but it is enough for many projects.

Example: a fan controller

As an illustration, we will build a distributed fan controller. In industrial environments, it is often important to remotely control devices such as fans and ovens. Indeed, most assembly lines in factories are managed from a central console.

The distributed fan controller consists of two elements:

  • the server, which interfaces with the device and exposes its services through a CORBA object (for the sake of simplicity, we will simulate a fan with

    println()
  • the client, which remotely controls the fan.

IDL interface

The first step when writing CORBA objects is to describe them in IDL. Just like Java interfaces, these are abstract descriptions of classes. However, IDL is not a programming language, and the interfaces must be compiled in the target language, such as Java, for implementation. IDL precompilers are available for the most popular languages, including Java, C++, and Cobol.

The IDL interface for the fan object is in listing 1. It defines two methods:

  • setSwitch()
    to turn the fan on and off
  • isSwitch()
    to report the status of the fan.


interface Fan
{
void setSwitch(in boolean b);
boolean isSwitch();
};

Listing 1: fan.idl

IDL syntax is close to Java; however, note the use of the

in
modifier before the

b
parameter. It signals an input parameter. IDL also supports the

out
modifier to flag parameters used to return a value and the

inout
modifier that combines both in and out.

To compile the interface in Java, invoke the

idltojava
precompiler with

idltojava fan.idl
. Note that at the time of this writing, the precompiler is a separate download available at java.sun.com. The precompiler depends on a C++ precompiler for some operations. If no C++ compiler is installed on your system, try

idltojava -fno-cpp fan.idl
.

The precompiler generates several Java files that implement network-related operations on fan objects.

Writing the client

The client is straightforward (see listing 2). It finds the remote object and invokes a method. It accepts the object name and a command on the command line.

There is very little CORBA-specific code in listing 2. The client initializes the ORB and obtains a reference to the naming service. The naming service is like a directory where the server can publish remote objects. Clients consult the directory to obtain a reference to specific objects.

Finally, it uses the naming service to obtain a reference to a remote object. The magic of CORBA is that the remote object behaves exactly like a local one. Once the client has a reference to a remote object, it uses it like a local object.


import org.omg.CORBA.*;
import org.omg.CosNaming.*;

public class FanClient
{
static public void main(String[] args)
throws Exception
{
// supply default values if required
String command = args.length < 1 ? "query" : args[0], objectname = args.length < 2 ? "default_Fan" : args[1]; // initialize the ORB and find the remote object ORB orb = ORB.init(args,null); NamingContext root = NamingContextHelper.narrow( orb.resolve_initial_references("NameService")); NameComponent[] path = { new NameComponent(objectname,"") }; Fan remoteFan = FanHelper.narrow(root.resolve(path)); // from now on, "normal" OO code if(command.equalsIgnoreCase("on")) remoteFan.setSwitch(true); else if(command.equalsIgnoreCase("off")) remoteFan.setSwitch(false); else System.out.println(objectname + ": " + (remoteFan.isSwitch() ? "on" : "off")); } }

[Ed. note: Some lines broken for presentation purposes.]

Listing 2: FanClient.java

Writing the server

The server isn’t much more difficult. It consists of two classes: an implementation of the Fan interface (listing 3) and the server process (listing 4).


public class FanImpl extends _FanImplBase
{
private boolean switchValue = false;
public void setSwitch(boolean b)
{
switchValue = b;
System.out.println(“turn ” +
(switchValue ? “on” : “off”));
}
public boolean isSwitch()
{
System.out.println(“query: ” +
(switchValue ? “on” : “off”));
return switchValue;
}
}

Listing 3: FanImpl.java

Again there’s very little CORBA-specific code: Inheriting from

_FanImplBase
, one of the classes generated by the precompiler is enough to turn

FanImpl
into a remote object! Consider how much code would be required to achieve the same result with low-level sockets.

Remote objects live in server processes; therefore, we need to write a server (a

main()
method) for our object.


import org.omg.CORBA.*;
import org.omg.CosNaming.*;

public class FanServer
{
static public void main(String[] args)
throws Exception
{
// default values, if required
String objectname = args.length
< 1 ? "default_Fan" : args[0]; // initialize the ORB ORB orb = ORB.init(args,null); // create the fan object Fan fan = new FanImpl(); // export the newly created object orb.connect(fan); // register the object with the name service NamingContext root = NamingContextHelper.narrow( orb.resolve_initial_references("NameService")); NameComponent[] path = { new NameComponent(objectname,"") }; root.rebind(path,fan); // wait forever Thread.currentThread().join(); } }

[Ed. note: Some lines broken for presentation purposes.]

Listing 4: FanServer.java

The server process contains more CORBA-specific code. The server creates an instance of

FanImpl
and makes it available through the ORB by calling

connect()
. Next, it registers the object with the name service so that clients can find it.

Wrapping it up

When compiling the server, the Java compiler complains that

_FanImplBase
calls deprecated APIs. Since

_FanImplBase
was generated by the precompiler, this is a problem for Sun to fix, not you.

For testing, you must first start the naming server by issuing

start tnameserv
on Windows NT or

tnameserv&
on Unix machines. Note that it is normal that upon starting, it prints a long string of hexadecimals. Next, start one or more servers in the background through

start java FanServer Fan01
(on Windows NT) or

java FanServer Fan01&
(on Unix) where “Fan01” is the name of the remote object.

Use clients to remotely administer the servers, e.g.,

java FanClient on Fan01
. Watch the console of the server during testing. If possible, run clients and servers on different machines.

Conclusion

CORBA takes the pain out of network programming. Remote objects behave like local ones, and they are not very difficult to write. By adding CORBA support to Java 2, Sun has reached another milestone in the integration of CORBA and Java.

[1] What is Java IDL?

About the author

Benoît Marchal runs his own consulting company, Pineapplesoft. His interests include distributed applications, object-oriented programming and design, system programming, hand-helds, and computer languages (notably Java). He also enjoys teaching and writing. bmarchal@pineapplesoft.com.


Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories