Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

.NET

Java Q&A


Dr. Dobb's Journal January 1997: How Do I Use CORBA from Java?

How Do I Use CORBA from Java?

Cliff, vice president of technology of Digital Focus, can be contacted at [email protected]. To submit questions, check out the Java Developer FAQ Web site at http://www.digitalfocus.com/faq/.


The Common Object Request Broker Architecture (CORBA) is a standard architecture for designing interoperable software components for heterogeneous computing networks. Modules written in various languages can be used together, exchanging objects and method calls across the network without your having to consider the nature of the underlying network or environments. Clearly, CORBA will play a major role in distributed computing.

This month, I'll examine how you can use Java to implement a CORBA application that is representative of the way that CORBA is likely to be used. In doing so, I'll revisit the chat application from my June 1996 column. For more information on CORBA, refer to "Networking Objects with CORBA," by Mark Betz (DDJ, November 1995); "OMG's CORBA," by Mark Betz (Dr. Dobb's Special Report on Interoperable Objects, Winter 1994/95); or CORBA Fundamentals and Programming, by Jon Siegel et al. (Wiley, 1996).

Why Use CORBA?

If the chat program worked fine without it, why use CORBA? Recall that, to build the chat program, I had to implement a simple protocol between the client and server: Clients sent characters to the server, then the server echoed those characters to all clients. However, to add features to the chat program -- allowing users to identify themselves by name, for example -- you would have to build a layered protocol (on top of the data stream) that could contain such control information. Consequently, you would end up writing Java classes to manage that protocol and all of its mechanics.

CORBA does this for you. In a CORBA application, you can concentrate on what methods you want to provide on the client and server, and forget about how you send that information back and forth. CORBA provides a way to create remote objects (on which you can make remote method calls). Further, the resulting protocol is independent of the implementation language, so you can mix components written in Java with components written in C++ and other languages. The interfaces for the components are written in the IDL specification language; CORBA vendors typically provide IDL compilers that generate code in your language of choice. This makes CORBA ideal for integrating new software with legacy systems written in a variety of languages.

Furthermore, Netscape will incorporate the Visigenic CORBA implementation (written in Java) into Navigator. Thus, the most popular browser will contain embedded CORBA classes that can be used in your Java applets, eliminating the time that would normally be required for the browser to download those components.

Choosing a CORBA Provider

Many companies are providing CORBA Java implementations (bindings), including Sun. At the time of this writing, however, Sun's Java implementation is relatively new. In particular, Sun does not yet provide the important IIOP protocol -- a sort of lingua franca for CORBA. All CORBA implementations are supposed to provide IIOP. Sun's surely will -- it just isn't ready yet (although it may be by the time you read this). Another consideration is that the version you choose should provide full CORBA 2.0 compatibility. This includes the capability for applets to act as servers. You might, at first, think that you would never write an applet that is a server. After all, if you cannot guarantee an applet will be reliably available, how can it ever be a practical server? However, when you start using CORBA, you will find that an applet server is the most effective way to design a system that automatically updates changes in state in client applets. For example, assume there is an update to a database in the midst of a user composing a new transaction; with CORBA, all the server has to do is call a method that executes on the client asynchronously. In this scenario, the client acts as a CORBA server whenever it receives and handles a remote method call from the main "server."

CORBA-fying the Chat Program

Recall that the chat system consists of a server program and multiple chat clients -- all communicating. The server serializes the interactions of the chatting clients and provides services (such as user identification and the like).

The first step in designing a CORBA service is to define its call interface -- the set of methods that clients of the service will call remotely. Remote method invocation is similar to remote procedure call (RPC), with the additional capability to pass objects around the network and invoke methods in the context of a remote object.

Passing parameters and objects around is known as "marshaling." To marshal, according to the Random House online dictionary, is to "arrange in proper or effective order" -- and that is what CORBA does when it marshals our method calls and parameters. It converts them into a stream of bytes that can be sent serially across a network, then unmarshaled at the other end so that the receiving CORBA interface can make sense of the bytes and know what method to call.

Since both the chat client and chat server will be acting as CORBA servers, you need to define two CORBA call interfaces. It is standard practice in CORBA applications to use IDL to define interfaces. Fortunately, IDL is similar to Java. Our chat server (implemented in IDL) contains the methods in Listing One and maps very closely to Java. When you run Listing One through an IDL compiler to generate Java code, the compiler generates a client stub and server skeleton. You don't have to mess with the stub: It is the piece of code that does all of the marshaling for the CORBA client. For example, when the client calls putLine(), it is actually calling a method in the generated stub. The stub marshals the method name and parameters into a stream, then sends this to the CORBA server (a program that makes a set of methods available to remote clients), which then unmarshals the stream and, depending on which method name is specified, calls the appropriate method on the server.

The skeleton is the empty set of methods on the server that get called -- you must fill in these empty methods with real code. In a typical Java implementation of CORBA, the generated skeleton is an interface, and all you have to do is implement the interface in a class, then create an instance of that class when publishing the service. Our implementation of this interface is called ChatServerSvcsImpl.

Clients find the CORBA service because it is registered with an Object Request Broker (ORB) that provides an object identification service. This means that the service has chosen a name for itself and announced that name to the ORB via an obj_is_ready() method call. The ORB is an application that is provided by your CORBA vendor and normally runs on the same machine that hosts the Java applet.

Whenever users type a character into the text window on the chat client, the client intercepts the event and, rather than display the character, calls putc(char) on the server. The server then goes down its list of clients, telling each client to insert a character at the same position in its client text area. To do this, the server calls a similar method, also called putc(), but on each client. The client is acting as a server (because it is providing a method that can be called remotely). Listing Two is the full chat-client interface. The list of methods is shorter because the client does not require methods for registering new clients, and so on.

Since the chat client is also a CORBA server, it will have a stub and a skeleton. In this case, the stub will execute on the chat-server platform, and the skeleton will execute on the chat-client platform. The stub provides the interface for the chat server to call whenever it wants to update a chat client. The skeleton is the chat client's bridge between the CORBA machinery and client's remote-call interface. Our client code has to contain a class that implements the skeleton (just like the chat server). This class is called ChatClientSvcsImpl.

The implementation of chat-client methods is straightforward. When putc() is called (remotely), the chat client merely appends a character to the user's text area. The backspace() method is a little more complicated; see Listing Three.

Since this is a chat application, you do not want users to be able to modify the chat history -- they should only be able to append text. Therefore, backspace() has to make sure that the client is positioned at the end of the text area. It does this by calling the Java AWT method TextArea.appendText() with an empty string as input. This places the insert position at the end of the text area. It then replaces the character at the end with an empty string -- effectively deleting the character.

To use these interfaces, you create a ChatClient and ChatServer class. Our ChatServer class is almost trivial. Listing Four, the main routine, performs these calls.

The constant NAME_OF_CHAT_SERVER_SVCS is the string name of the service we want to publish; in our case, we use ChatServerSvcs, although it could be anything. The CORBA.ORB.init() call initialized the connection to the ORB, and the BOA_init() starts the component that allows this program to be a server. obj_ is_ready() registers the actual instance of ChatServerSvcsImpl servicing the incoming calls -- the CORBA skeleton will forward incoming requests to this object; this object must implement the skeleton Java interface generated from the IDL compiler.

The ChatClient class is more complex. It starts the ORB link by calling the CORBA init() method, then instantiates the text area and a Connect/Disconnect button. I have an action() method for handling button events. When users click the Connect button, action executes Listing Five.

The first line asks the server to reserve a name for the new client. I would prefer to have the server choose a name as part of the open() call, but it cannot because you cannot call open() until you have constructed a ChatClientSvcsImpl object, and that requires a service name. Since there is a chicken-and-egg problem with getting the name in the open() call, I designed the ChatServerSvcs to provide the getUniqueName() method (to allow the client to determine a unique name for itself, since there will be multiple clients chatting).

After you call obj_is_ready(), the client service can accept remote calls. You do not have to call impl_is_ready(); this method forces the program to block if it is only listening for requests, because Java will terminate the virtual machine if only daemon threads are running. In the case of the chat client, the user-interface components are running, so you do not have to worry about the program terminating.

Finally, the call to open() is a remote call to the ChatServerSvcs, which registers the client with the server. It adds the chatClientSvcs instance to the server's list of clients. It also associates the userName with that instance, in case it needs it later. Figure 1 shows this applet. The complete source code is available electronically from DDJ (see "Availability," page 3), and at the Digital Focus site (http://www.digitalfocus.com/ddj/code). The Visigenic Java toolkit is at Visigenic's web site (http://www.visigenic.com).

Other Issues

One difficulty encountered with using a Java CORBA applet from a browser is that the applet may need to access remote objects on multiple servers -- but the browser will not allow the applet to open a connection to any machine other than the one it came from. CORBA vendors have solved this problem by building proxy components into their server-side software. These components forward object requests to other machines when needed. Also, some firewalls will not pass the object stream that CORBA protocols require. Some CORBA vendors address this problem by piggybacking the object stream onto the HTTP protocol, to get it past a firewall, then reextracting the stream at the server side.

It would also be nice if it were possible to write only in Java (and not have to use IDL). Visigenic's next release allows you to do this -- it generates stubs and skeletons directly from compiled Java interfaces.

Summary

CORBA provides a powerful alternative to CGI. You can write true distributed programs, treating the Internet as one giant operating system. Gone are the days of stuffing parameters into CGI input streams and generating HTML output. A Java client can interact directly with a server-based program using distributed protocols such as CORBA. What's more, the interaction can be bidirectional, making it possible for the server to update the client when changes of state occur, without the client having to poll. The possibilities are limitless. Netscape's decision to bundle a robust Java CORBA facility into its set of built-in Java packages means that there is no overhead in using CORBA-ized Java applets within the Netscape environment. Other Java platforms are expected to follow suit and will soon provide similar embedded CORBA functionality. Regardless, a Java CORBA applet will work in any Java-enabled browser, whether the CORBA functionality is embedded or not. You can expect to see a lot of CORBA from now on.

DDJ

Listing One

interface ChatServerSvcs{
   string getUniqueName(in string baseName)
         raises (Project::CannotEstablishConnection);
   void open(in string clientName, in ChatClientSvcs cc)
         raises (Project::CannotEstablishConnection);
   void close(in string clientName)
         raises (UnidentifiedUser);
   void putc(in char cin);
   void puts(in string sin);
   void putLine(in string sin);
   void backspace();
   UserList getUsers();
   void identifySelf(in string oldname, in string newname)
         raises (NonUniqueUser, UnidentifiedUser);
};

Back to Article

Listing Two

interface ChatClientSvcs{
   void putc(in char cin);


</p>
   void puts(in string sin);
   void putLine(in string sin);
   void backspace();
};

Back to Article

Listing Three

public void backspace(){
   textArea.appendText("");    // position insert position at the end
   int curpos = textArea.getSelectionStart();
   if (curpos == 0) return;
   textArea.replaceText("", curpos-1, curpos);
}

Back to Article

Listing Four

orb = CORBA.ORB.init();boa = orb.BOA_init();
chatServerSvcs = new ChatServerSvcsImpl(NAME_OF_CHAT_SERVER_SVCS);
boa.obj_is_ready(chatServerSvcs);
boa.impl_is_ready();

Back to Article

Listing Five

userName = chatServerSvcs.getUniqueName(BASE_NAME_OF_CHAT_CLIENT_SVCS + ".");boa = orb.BOA_init();
chatClientSvcs = new ChatClientSvcsImpl(userName, textArea);
boa.obj_is_ready(chatClientSvcs);
chatServerSvcs.open(userName, chatClientSvcs);

Back to Article


Copyright © 1997, Dr. Dobb's Journal


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.