Oracle8i's ORB does the trick

Develop scalable and secure Java CORBA applications with Oracle8i

Oracle8i features a built-in JVM, an embedded ORB (object request broker) based on OMG's (Object Management Group) CORBA specification, and useful services such as an EJB component model. In this article, we'll look at the Java-based Oracle8i Aurora ORB's distinguishing features and demonstrate how to develop applications with it. OMG's CORBA architecture is the industry's most-deployed distributed component model. Oracle8i's integrated JVM uses the database's session-based architecture to achieve better scalability, so Oracle8i's embedded ORB provides scalability and rich functionality interoperable with other ORBs.

Oracle8i also comes with an EJB container. EJB is simpler from an end user's perspective because of its declarative security and transactional attributes, but a large number of applications still use ORB technology because of its language independence. Oracle8i's ORB and embedded services such as NameService and Security Service make it a powerful component model. The clear ORB interoperability standards also enable the mixing and matching of ORBs from different vendors and languages, as well as support for legacy applications written in non-Java languages. We'll also look at guidelines for interoperability with other ORBs and support for C++ clients. So, if you are a Java developer wanting to develop large-scale distributed and scalable applications, this article is for you.

Note: From this point on, I'll refer to the Oracle8i ORB as Aurora ORB, Oracle's code name for its ORB product. The ORB features listed will be part of Oracle's 8.1.6 release, which will support both JDK 1.1 and JDK 1.2.

FIGURE 1. The big picture

Features of Aurora ORB

Oracle 8.1.6's Aurora ORB, based on Inprise's vbroker Java code base, complies with OMG CORBA 2.0 specifications (with one exception: it supports GIOP 1.0 but not GIOP 1.1). Aurora ORB's current version supports BOA (Basic Object Adapter) but not POA (Portable Object Adapter). Nearly all applications access a database at some point. Since Aurora ORB runs inside the database, it facilitates ORB-server applications' database access by using the default JDBC connections. Details can be found in Oracle JDBC manuals. (See Resources for a link.)

Aurora ORB's features include:

  • The ORB core
  • The COS naming and bootstrapping services
  • Implicit activation of factory objects on first lookup
  • JNDI SPI (Service Provider Interface) for COS naming
  • Strong Security (authentication and authorization) services that do security checks at various levels
  • IIOP/SSL (both server-side and client-side authentication)
  • Session-based IIOP, whereby a single client can access multiple sessions
  • OTS/JTS supporting single resource
  • Interface Repository (beta)
  • Highly scalable server architecture
  • Caffeine (generates IIOP stubs from a Java class without using IDL files)

Developing CORBA applications

Except for small variations in exporting (to a name service) and activating objects, writing an application for CORBA is generally the same as for almost any ORB, including Aurora ORB. However, there is one clear difference in Aurora ORB: because its server code runs in the database, you need to load the Java classes to the database, as explained below. Let's take a step-by-step look at how to write a CORBA application with Aurora ORB:

  1. Define interfaces and write the IDL (or use Caffeine): You need to define your server-object interfaces, in the form of a language-neutral CORBA IDL file.
  2. Code generation: Run the aforementioned IDL file through the idl2java compiler, thus generating the necessary client stubs, server skeletons, and utility classes such as Helper and Holder.
  3. Server-object implementation: Implement your server object. The implementation class should usually extend the generated skeleton-implementation base class. Java doesn't support multiple inheritance, so to extend your implementation class, the object implementation needs to implement an interface class (called <your_interface_name>Operations.java) known as a tie mechanism, rather than extending the skeleton-implementation base class. After the tie mechanism, the object implementation also needs to implement Aurora ORB's ActivatableObject interface. ActivatableObject has one method: initializeAuroraObject(), which the ORB will invoke upon activation. You'll also need to do the tie initialization in the initializeAuroraObject() method.
  4. Client implementation: Implement your client application.
  5. Load the Java classes into the database: As mentioned earlier, loading the Java classes into the database is an unnecessary step for stand-alone ORBs running outside a database. Use the loadjava tool to load the classes.
  6. Publish the objects to the COS name service: Publish the server object to the COS name service while specifying the requisite security access permissions.

One of the first steps in locating CORBA server objects is to find BootService/NameService, which can look up the requested server objects. With that in mind, let's turn our attention to bootstrapping.

How to use bootstrapping and the JNDI interface

Aurora ORB implements the BootService mechanism developed by Oracle and others a couple of years ago. BootService defines an interface so it can register services and query for those services. BootService runs on a well-known port for easy client access. Constructing the BootService client-proxy object reference on the fly is simple because of the service's well-known port and object key. ORB clients will first resolve BootService, then query for the name-service reference. Then, using the standard COS name service interface, one can interact with the name service for binding and resolving objects.

Oracle has extended the COS name service interface to support automatic object activation and to return appropriately narrowed-down objects upon lookup. In addition, Oracle implemented the URL-based JNDI SPI for the COS name service, so Java clients can simply perform JNDI object lookups. The JNDI lookup returns the appropriately narrowed-down CORBA objects, and the clients can invoke methods on those objects, just like on regular Java objects. In other words, all the complexity of locating the name service, etc., is taken care of by JNDI lookup; the client applications need not worry about the details. However, if a sophisticated client wants to directly use the name service, it may do so using the standard CORBA interface. Oracle ships examples of this sort with the release, and provides a command line tool to register objects with its name service. (See Resources.)

Currently, only top-level stateless factory objects can be published with the name service. User-created transient objects cannot be registered with the service. This restriction will be lifted in the future release; Oracle will support a pure JNDI-based name service that will include federation across different name spaces.

In the next section, we'll examine a new concept called session-based IIOP, an essential feature for scalability and middle-tier server applications.

Session-based IIOP

CORBA object references are usually distinguished by their host, port, and object key tuples. The ORB runtime typically decides to make new connections to the server only if there is no existing connection to the host and port specified by the object reference it is trying to access. If there is an existing connection, it will send the requests to any objects with that host and port on the same connection. The ORB server dispatcher hands the request to the appropriate object, based on the request's object key. Consequently, CORBA doesn't have the concept of sessions, which is important for scalability. With the existing mechanism, there is no way to distinguish object references in different sessions. Obviously, an Oracle database is session-oriented. To take advantage of this, Oracle introduced an additional parameter for distinguishing object references, namely the session in which they are activated. Oracle used the standard component tag method to insert this session information in the object reference.

The connection management in the ORB client now uses not only the host and port, but also the session information -- called session-based IIOP. There is no change in the IIOP wire format, allowing a single client to explicitly access or create objects in multiple sessions. As per OMG specifications, the implementation is flexible enough that third-party ORBs that don't support session-based IIOP will simply ignore additional component tags and do the normal connection management. Moreover, Oracle reserved a separate server port for connecting with regular IIOP connection management.

The above discussion demonstrates a feature whereby a single client will be able to access multiple server sessions, a feature required to deploy Oracle8i as a middle tier. On the other hand, there are also cases when multiple CORBA clients need to be able to go into a single session. For example, if a client created an object reference in a session and passed it along to another client, that second client should be able to go to that session to access the same instance. Oracle achieves this by implementing session routing on the server. Session routing remains transparent to clients and requires no changes to either the client or the client ORB.

Oracle is in the process of including the session component tag in the standard CORBA specification.

In addition to robustness and scalability, security is an important part of any application. Having talked about the scalability aspects through session-based architecture, it's time now to consider the security aspect of the Aurora ORB.

Security and SSL

Appropriate security checks are made at various levels before access is given to a session or object in the server. The database is a highly secure environment and you'll need to authenticate to it before you can do anything. Since the CORBA server code runs inside the database, the same rule applies. Therefore, in the case of CORBA clients, Oracle provides several means of authentication:

  • Pass in the username/password (supplied by the user) implicitly in a security context to the server on the first message
  • Explicitly log in using a prepublished CORBA login object
  • Use SSL client-side authentication

Examining these mechanisms in detail is beyond the scope of our discussion, but we can focus on some important considerations. To begin, the username/password is never sent naked to the server. It is either encrypted like an SSL connection or a challenge/response protocol is used. The clients indicate programmatically what type of authentication mechanism they prefer. In the case of username/password (whether it is a non-SSL connection or a server-side-auth-only SSL connection), the database session is authorized to that user. In the case of SSL client-side authentication, the client's certificate is used (actually, the DN in the certificate is treated as a global user name) to authorize the session.

Once the user is authenticated to the database and a session is created and authorized to that user, other security checks come into play. In case of security violations, a CORBA NO_PERMISSION system exception is thrown, with appropriate minor codes. For details on how to explicitly grant access to items at various levels, refer to the Oracle8i manuals. (See Resources.) Although not a complete list, here are some of the security checks:

  • The user must first authenticate to the database using one of the mechanisms discussed above. Even if the user is connecting to an existing session, authentication is still necessary.
  • If the user doesn't have read and execute access to the object being looked up in the name service, access will be denied.
  • If the user doesn't possess execute privileges on the actual implementation class, access will be denied.
  • A user can't access classes in someone else's schema unless explicitly granted permission.
  • Security checks at various levels are made as per the Java 2 security model (e.g. performing socket and file operations, reading system properties, and debugging privileges).
  • General database security checks apply while doing any SQL (using JDBC or SQLJ).
  • If the server enforces use of SSL, connections will be refused for non-SSL clients.

Sample code

Now that we've looked at Aurora ORB's features and concepts, let's learn how to write a simple "Hello, World" non-SSL CORBA application with Oracle8i.

Interface definition

Let's say the following is the definition of a Hello object expressed in the IDL file hello.idl:

   module hello {
      interface Hello {
         wstring helloWorld ();
      };
   };

As you can see, the Hello object's single method -- helloWorld() -- returns a string of wide characters (capable of storing multi-byte characters).

Code generation

We now need to run our IDL file through the IDL compiler to generate the client stubs, server skeletons, and some utility classes. At the command line, type:

idl2java  hello.idl

The above command will produce stub/skeleton files in the package hello, as specified in the IDL file (module specification).

Server implementation

Let's now implement the hello server object as follows (in HelloImpl.java):

1 2 Page 1
Page 1 of 2