The latest release of the Apache Geronimo server, M5 (Milestone 5; see Resources for a link), contains enhancements in the area of interoperability with external systems using CORBA. If you're already initiated into CORBA, you know the importance of this capability and how it may affect the viability of a J2EE server for a particular project.
In addition to being the external interface mechanism of choice for many legacy computing systems -- from mainframes to supercomputers -- CORBA is a widely adopted distributed object mechanism for large, mission-critical real-time-control, telecommunications, banking, and defense systems. There are many situations in which these systems need to access information or business logic managed within the J2EE server's domain (and vice versa). For this access to happen smoothly, without complex custom coding, interoperability between CORBA and J2EE components is an essential basic requirement.
Geronimo's CORBA interoperability implementation allows CORBA client applications to access business logic contained in Enterprise JavaBeans™ (EJBs) and data managed by J2EE's business tier.
This article demonstrates how to use the CORBA interoperability capabilities of the Geronimo M5 release. It provides a complete example of a CORBA client accessing business-tier EJBs managed by the Geronimo server. The client takes advantage of the support provided by the Geronimo client application container.
CORBA provides standards-based infrastructure for interactions between distributed objects. It allows software components running on dissimilar hardware, hosted on different operating systems, and programmed in different programming languages to communicate, collaborate, and perform productive work over a network.
A CORBA system accomplishes this magical task by confining the interaction between objects to well-defined interfaces. To use the service of a distributed object, you must interact with it through the interface. How the interface is implemented -- or even where it is implemented -- is not known and doesn't have to be known by the client. Figure 1 illustrates the workings of a typical CORBA system.
Figure 1. Object interactions in CORBA
Achieving location transparency
In Figure 1, the client code makes use of a server object through its interface. In fact, the interface is implemented by a stub object that is local to the client. As far as the client can tell, it's only interacting with the local stub object. Under the hood, the stub object implements the same interface as the remote server object. When the client invokes methods on the interface, the stub object forwards the call to a CORBA component called the Object Request Broker (ORB). The calling code in the client does not have to know that the call is actually going through a stub.
The ORB is the centerpiece of the CORBA infrastructure. It's responsible for locating the server object (wherever it may be over the network) and then sending the stub’s call to the server. After the call is completed, the return value is returned to the ORB over the network, and the ORB hands it back to the stub. The stub then returns from the client invocation. As far as the client can tell, the stub object is the implementer of the interface.
At the server end, the ORB also has important duties. It has to take the method invocation coming from the client’s ORB and forward that call to a skeleton object, which is a direct parallel of the stub on the client side. It masks the network call from the point of view of the server logic -- implementing the interface. The skeleton object makes only local calls on the server to the object that implements the interface on the server machine.
The need for different ORB implementations to communicate
The exact implementation details of an ORB can differ from one vendor to another. For one vendor an ORB may be implemented as library code that is linked to the client/server executables. For another it may be a collaboration between a layer of library code and a daemon process running on the same machine. In any case, CORBA ORBs from different vendors should all be able to talk to one another thanks to the standardization of the CORBA communication protocol over the Internet, called the Internet InterORB Protocol (IIOP). Figure 1 shows two ORBs communicating through IIOP.
Interoperability between ORBs through IIOP
IIOP is a specialization of the General Inter-ORB Protocol (GIOP) over TCP/IP networks for the Internet. Since CORBA 2.0, the ability for ORBs of different vendors to work together was made a requirement by the specification. Today, IIOP is widely used for interoperability between different ORB implementations and between Java Remote Method Invocation (RMI) and CORBA systems.
RMI-IIOP: Enabling Java-to-CORBA interoperability
In Java Development Kit (JDK) 1.4 and beyond, you can choose to use the IIOP protocol to communicate between Java RMI objects. In the past, only the proprietary Java Remote Messaging Protocol (JRMP) was used for RMI. Both JRMP and IIOP are used to send message invocation information or return values over the wire. The ability of RMI objects to use IIOP means that Java-based RMI clients can access CORBA remote objects, and CORBA clients can access RMI-implemented objects. This interoperability is important in enabling Java objects to access legacy CORBA-based resources as well as in opening Java server resources (such as EJBs) for access by other CORBA clients.
CORBA IDL -- Remote object access based on interfaces
The objects in a CORBA system are accessed exclusively through interfaces. Interfaces are defined, in CORBA, in a standardized format called Interface Definition Language (IDL), which is neutral from a specific programming language. Figure 2 shows how IDL integrates the server objects and clients together.
Figure 2. Generating stubs and skeletons from IDL
For each supported programming language, tools are provided to generate native language binding. A binding is typically generated source code in the supported programming language (for example, a Java binding is in Java, and a C++ binding is in C++ source code). The generated code is then compiled and linked together with the user written code. Even though the binding is a source text file -- which can be easily modified like most generated code -- it should never be modified, because regeneration will wipe out all modifications. The generated code includes the stubs on the client side (implementing the required interface), and the skeleton on the server side. It also includes some useful helper methods for converting between data types in the associated programming language.
The CORBA architecture features the notion of an object bus. Any client or server implementation connected to this bus through the ORB can interact with and make use of a set of well-defined and standardized CORBA services. Figure 3 illustrates a CORBA object bus.
Figure 3. A CORBA object bus
In Figure 3, the services include a Naming service, an Interface repository (for storing and retrieving interface and type descriptions), and a Time service.
The Naming service is a frequently used service in CORBA. The Object Management Group (OMG; see Resources for a link to the OMG site) specifies an Interoperable Naming Service (INS). The idea is straightforward and similar in operation to the RMI registry. Basically, the server creates an instance of a remotely accessible object, binds it using the ORB to take incoming requests, and then registers the availability of the instance with the Naming service under a well-known or advertised textual name. Any client that needs to use the service of the server can then contact the Naming service and look up the server using the textual name to obtain the remote object reference.
Unifying object reference lookup using JNDI
When coding in the Java programming language, the J2EE integration with Java Naming and Directory Interface (JNDI) enables developers to write object lookup code that works with a variety of directory and naming services. Client code should call JNDI, and JNDI forwards to the applicable service underneath through a provider implementation. A CosNaming provider is available within the JDK, allowing the JNDI code to use the CORBA naming service for object lookup. Figure 4 illustrates the use of JNDI to look up remote CORBA objects.
Figure 4. Performing JNDI-based CORBA lookup
Figure 4 also shows that RMI-IIOP, when used in conjunction with a JNDI-based CORBA lookup, can readily enable developers to write one single code base that works with either RMI-based servers or CORBA-based servers.
Geronimo's CORBA interoperability implementation
With this fundamental understanding, it's a good time to take a look at how Geronimo interoperates with external CORBA clients and components. Figure 5 shows the common interoperability possibilities. They include:
- A Web-tier or EJB-tier Java client invoking methods on external CORBA components.
- EJB components running inside a Geronimo server exposed through IIOP for remote access by CORBA-based clients.
- An application client using the Geronimo client application container, accessing remote CORBA components.
In all of the above cases, the client or server code hosted inside Geronimo must communicate with the external CORBA component over IIOP and through an ORB. The standard distribution of the JDK comes with an ORB implementation from Sun Microsystems, often known as the Sun ORB. Geronimo M5 makes use of this ORB for interoperability (see Geronimo's ORB choices for more information).
Figure 5. Geronimo CORBA interoperability scenarios
Enabling CORBA interoperability -- it's all about configuration
With Geronimo, EJBs can be exposed as CORBA servers through configuration at deployment time. This means that you don't have to do any special coding in your EJBs. In fact, any existing EJB can be exposed as a CORBA server object.
Consider our example, a simple stateless session bean that exposes a method to read the server-side timestamp. The code for the EJB interface is shown in Listing 1.
Listing 1. EJB interface for server timestamp stateless session EJB
package com.ibm.dw.geronimo.corba;
public interface ServerTimestamp extends javax.ejb.EJBObject {
public String getTimestamp() throws java.rmi.RemoteException;
}
|
The actual implementation of the EJB interface is in the com.ibm.dw.geronimo.corba.ServerTimestampImpl class, and shown in Listing 2.
Listing 2. Implementation of server timestamp EJB
package com.ibm.dw.geronimo.corba;
import java.util.Date;
public class ServerTimestampImpl implements javax.ejb.SessionBean {
public String getTimestamp(){
return "This is the current server time " + new Date();
}
private javax.ejb.SessionContext mySessionCtx;
public javax.ejb.SessionContext getSessionContext() {
return mySessionCtx;
}
public void setSessionContext(javax.ejb.SessionContext ctx) {
mySessionCtx = ctx;
}
public void ejbCreate() throws javax.ejb.CreateException {
}
public void ejbActivate() {
}
public void ejbPassivate() {
}
public void ejbRemove() {
}
}
|
Notice in the code of both Listing 1 and Listing 2, there is no specialized CORBA coding. In fact, even the deployment descriptor for the EJB is pretty ordinary. Listing 3 shows the ejb-jar.xml deployment descriptor for the timestamp EJB.
Listing 3. Deployment descriptor ejb-jar.xml for server timestamp EJB
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN'
'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
<enterprise-beans>
<session>
<display-name>Server timestamp Stateless Session Bean</display-name>
<ejb-name>ServerTimestampEJB</ejb-name>
<home>com.ibm.dw.geronimo.corba.ServerTimestampHome</home>
<remote>com.ibm.dw.geronimo.corba.ServerTimestamp</remote>
<ejb-class>com.ibm.dw.geronimo.corba.ServerTimestampImpl</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
|
The plain vanilla ejb-jar.xml in Listing 3 allows the resulting EJB JAR to be deployed on Geronimo or other J2EE 1.4 servers with no change.
Expose EJB for CORBA access in a custom deployment plan
To configure the EJB for CORBA access, you need to create a specialized Geronimo deployment plan for the bundle. This is maintained in the dp.xml file. Listing 4 shows the section of this plan that sets up EJB for remote CORBA client access.
Listing 4. Configuring server timestamp EJB for CORBA access
<?xml version="1.0" encoding="UTF-8"?>
<application
xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.0"
configId="com/ibm/dw/geronimo/corba/ServerTimestamp"
parentId="org/apache/geronimo/ServerCORBA">
<import>
<uri>org/apache/geronimo/Security</uri>
</import>
<module>
<ejb>dwcorba1-ejbs.jar</ejb>
<openejb-jar
xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.0"
configId="ServerTimestampEJB"
parentId="org/apache/geronimo/ServerCORBA">
<enterprise-beans>
<session>
<ejb-name>ServerTimestampEJB</ejb-name>
<jndi-name>ServerTimestampEJB</jndi-name>
<tss-link>IdentityTokenNoSecurity</tss-link>
</session>
</enterprise-beans>
</openejb-jar>
</module>
...
|
In Listing 4, you can see that we set up the parent configuration of the deployed .ear file as the org/apache/geronimo/ServerCORBA configuration. This configuration includes everything in the standard org/apache/geronimo/Server configuration, plus definitions of several CORBA-specific server-side GBeans. The <tss-link> element specifies one of these security handling GBeans, with the attribute value IdentityTokenNoSecurity. The next section explains the operation of this GBean.
GBean implementation of the CORBA 2.3 CSIv2 security requirements
Geronimo’s CORBA implementation is fully compliant with CORBA 2.3. CORBA 2.3 requires a security layer known as Common Security Interoperability, Version 2 (CSIv2). This layer negotiates the required level of security between a CORBA client and a server prior to allowing communications. (A future article will explore the ramifications of CSIv2 in greater detail.)
In Geronimo M5, the CSIv2 feature is implemented as a set of GBeans that you can configure when you expose EJBs for CORBA access.
In Listing 4, the <tss-link> selects one of the Target Security Service (TSS) implementation GBeans. The one it selects is called IdentityTokenNoSecurity, which is configured in the org/apache/geronimo/ServerCORBA deployment plan to allow access without authentication or encryption.
This is all that is required to expose the EJB for CORBA access. The parent org/apache/geronimo/ServerCORBA configuration starts a CORBA Naming service and registers the EJB as an available CORBA server object upon module startup.
Creating a Swing-based CORBA client application
To access the EJB as a CORBA object, you need to create a simple GUI client application that runs in the Geronimo application client container. The source code components for this client are enumerated in Table 2. You can cross-reference the table against the code distribution.
| Code component | Description |
|---|---|
| TimestampDisplayClient.java | Trivial main class for the client application that constructs an instance of TimestampFrame and displays it. |
| TimestampFrame.java | A JFrame subclass that uses JDK's built-in RMI-IIOP to access remote CORBA server timestamp objects. It obtains the timestamp from the remote CORBA server and then displays it on its own Swing-based GUI. |
| SecurityCallbackHandler.java | The Client Security Service (CSS)-handling GBean invokes this handler. Typically, when the server requires a username and password for authentication, this handler can display a user interface to collect this information. The example in this case does not use this handler. |
| com.ibm.dw.geronimo.corba.ServerTimestamp.class com.ibm.dw.geronimo.corba.ServerTimestampHome.class | These EJB Java class files are required to compile TimestampFrame.java properly. |
The source code for the TimestampFrame.java is shown in Listing 5. This is the actual class that invokes the method on the remote EJB/CORBA object.
Listing 5. RMI-IIOP invocation in TimestampFrame.java
package com.ibm.dw.geronimo.corba.client;
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import com.ibm.dw.geronimo.corba.ServerTimestampHome;
import com.ibm.dw.geronimo.corba.ServerTimestamp;
public class TimestampFrame extends JFrame{
public TimestampFrame(String title) {
super(title);
}
public void init() {
JLabel timeStamp = new JLabel(getTime());
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());
pane.add(timeStamp, BorderLayout.CENTER);
this.getContentPane().add(pane);
}
private String getTime() {
String retval = "";
ServerTimestamp ts = null;
try {
Context ic = new InitialContext();
Object o =
ic.lookup("java:comp/env/ServerTimestampEJB");
ServerTimestampHome home = (ServerTimestampHome)
PortableRemoteObject.narrow(o,
ServerTimestampHome.class);
ts = home.create();
retval = ts.getTimestamp();
} catch (Exception ex) {
ex.printStackTrace();
}
return retval;
}
}
|
In Listing 5, the object reference is obtained using a JNDI lookup using InitialContext. The object reference received is narrowed to the EJB home interface using PortableRemoteObject.narrow(). This code will work with remote CORBA objects and remote RMI objects over IIOP.
Dynamic runtime stub generation
Unlike the use of IDL-generated conventional Java binding (source code), Geronimo can dynamically generate CORBA stubs in binary. The client application takes advantage of this dynamic stub generation capability; the stub is generated when the ORB requests it for them.
Figure 6 reveals the Geronimo CORBA support available to application clients and server-side EJBs.
Figure 6. Geronimo's CORBA support
Wiring up CORBA client support
In the deployment plan for the application client, a GBean for handling the client side of CSIv2, called the CSS, is configured. The deploy.xml file specifies the CSS instance associated with the NoSecurity name. Listing 6 illustrates the configuration required for the application client.
Listing 6. Configuring the client application for CORBA access
<module>
<java>dwcorba1-clientapp.jar</java>
<application-client xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-client"
configId="client"
clientConfigId="com/ibm/dw/geronimo/corba/ServerTimestampClient"
clientParentId="org/apache/geronimo/ClientCORBA">
<import>
<uri>org/apache/geronimo/ClientSecurity</uri>
</import>
<ejb-ref>
<ref-name>ServerTimestampEJB</ref-name>
<ns-corbaloc>corbaloc::localhost:1050/NameService</ns-corbaloc>
<name>ServerTimestampEJB</name>
<css-link>NoSecurity</css-link>
</ejb-ref>
<realm-name>client-properties-realm</realm-name>
<callback-handler>
com.ibm.dw.geronimo.corba.client.SecurityCallbackHandler
</callback-handler>
</application-client>
</module>
|
In Listing 6, the parent configuration for the client application is set to org/geronimo/corba/ClientCORBA where the security GBean instances are configured. The <ns-corbaloc> element tells the Geronimo client application container where to find the CORBA naming service. The <css-link> tag specifies the security-handling GBean to use. The <callback-handler> tag specifies the callback method to use by the CSS GBean when requesting authentication information.
Running the CORBA client against the EJB
Looking in the bin directory of your Geronimo installation, locate the startup.bat file. You need to make the modifications shown in the highlighted lines in Listing 7. The modifications add the properties required to specify the Geronimo ORB support classes. (Future releases of Geronimo may make this process simpler.)
Listing 7. Modifications for startup.bat to add CORBA properties
for %%z in (%CUR_DIR%) do set CUR_DIR=%%~sz set GERONIMO_DIR=c:\gerbuild\geronimo-1.0-M5 set CORBA_OPTS=-Dorg.openejb.corba.UtilDelegateClass=com.sun.corba.se.internal.POA.ShutdownUtilDelegate -Dorg.omg.CORBA.ORBSingletonClass=com.sun.corba.se.internal.corba.ORBSingleton -Dorg.omg.CORBA.ORBClass=org.openejb.corba.sunorb.OpenEJBORB -Djavax.rmi.CORBA.PortableRemoteObjectClass=com.sun.corba.se.internal.javax.rmi.PortableRemoteObject -Djavax.rmi.CORBA.UtilClass=org.openejb.corba.util.UtilDelegateImpl set SSL_OPTS=-Djavax.net.ssl.keyStore=%GERONIMO_DIR%\var\security\keystore -Djavax.net.ssl.keyStorePassword=secret -Djavax.net.ssl.trustStore=%GERONIMO_DIR%\var\security\keystore -Djavax.net.ssl.trustStorePassword=secret @rem Set the path to the server.jar set SERVER_JAR="%~dp0server.jar" for %%z in (%SERVER_JAR%) do set SERVER_JAR=%%~sz :CheckServerJar ...... :StartServer echo on %JAVA% %CORBA_OPTS% %SSL_OPTS% -jar %SERVER_JAR% %ARGS% |
Make sure you set the GERONIMO_DIR variable to your own Geronimo installation directory. Each option line in Listing 7 must be typed as a continuous long line. Note that the SSL properties must be specified for the server; this is a restriction of the M5 server-side implementation. It's probably easier to paste the supplied startup.bat file over the one in your M5 bin directory. Use this modified startup.bat file to start the server.
An Ant build file has been supplied for building the example. You need to edit build.xml to reflect your Geronimo installation directory. To build the project, use the command:
ant ear |
You'll then find dwcorba1.ear in the dist subdirectory. To deploy the EAR containing both the EJB and the client application to Geronimo, use the following command from the Geronimo installation directory:
java -jar bin/deployer.jar --user=system --password=manager deploy dwcorba1.ear deploy.xml |
Make sure you have moved the dwcorba1.ear and dp.xml files to the same directory.
To run the client application, use the runclient.bat file from the source code distribution. This batch file sets the ORB support properties in the same way as the startup.bat file, this time for the client's Java VM. The runclient.bat file contains the following:
Listing 8. Batch file to start client application runclient.bat
java -Djavax.rmi.CORBA.UtilClass=org.openejb.corba.util.UtilDelegateImpl
-Dorg.openejb.corba.UtilDelegateClass=com.sun.corba.se.internal.POA.ShutdownUtilDelegate
-Dorg.omg.CORBA.ORBSingletonClass=com.sun.corba.se.internal.corba.ORBSingleton
-Dorg.omg.CORBA.ORBClass=org.openejb.corba.sunorb.OpenEJBORB
-Djavax.rmi.CORBA.PortableRemoteObjectClass=
com.sun.corba.se.internal.javax.rmi.PortableRemoteObject
-jar bin/client.jar com/ibm/dw/geronimo/corba/ServerTimestampClient
|
When you run the client, it displays the server timestamp on its GUI. This timestamp is obtained from a CORBA remote object, which is actually handled by a remote Geronimo EJB. Figure 7 shows the display of a successful client run.
Figure 7. Application client with server timestamp displayed
Geronimo CORBA interoperation enables you to leverage existing legacy system investments while integrating heterogeneous solutions, a frequently recurring task in modern enterprises.
| Description | Name | Size | Download method |
|---|---|---|---|
| Source code Geronimo CORBA example | code.zip | 300KB | HTTP |
Information about download methods
Learn
- Visit the The Object Management Group (OMG) site, your central source for all CORBA information and specifications.
- Get the latest milestone build of Geronimo from the official Apache Geronimo project site.
- Read "Creating client applications for Geronimo" (developerWorks, June 2005) to learn more about writing client applications for Geronimo using the client application container.
- Read "Dive into EJB Web applications with Geronimo" (developerWorks, July 2005) for a hands-on example on working with EJBs on Geronimo.
- Find helpful resources for beginners and experienced users at the Get started with Geronimo section of developerWorks.
- Get expert technical support from the IBM Support for Apache Geronimo program.
- Visit the developerWorks Apache Geronimo project area for articles, tutorials, and other resources to help you get started developing with Geronimo today.
- Check out the developerWorks developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
- Get information on the announcement of IBM WebSphere® Application Server Community Edition, as well as resources on other WebSphere products and technologies, at the developerWorks WebSphere home page.
Get products and technologies
- Innovate your next open source development project with IBM trial software, available for download or on DVD.
Discuss
- Participate in the discussion forum.
- Fellow Apache Geronimo developers gather in the Focus on Apache Geronimo forum here on developerWorks.

Sing Li is a consultant and freelance writer. He has contributed to Beginning JavaServer Pages, Professional Apache Tomcat 5, Pro JSP - Third Edition, Early Adopter JXTA, Professional Jini, Beginning J2ME: From Novice to Professional, Third Edition, and numerous other books. He is also a regular contributor to technical magazines and an active evangelist of the VON and P2P evolutions. You can reach Sing at westmakaha@yahoo.com.

After studying mathematics, work in biochemistry, and a career as a harpsichord maker, David Jencks returned to an early interest in software engineering. He has been a significant contributor to several open source projects, including Jaybird and, most importantly, Geronimo. You can reach David at david_jencks@yahoo.com.




