ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Local Invocation for CORBA
Pages: 1, 2, 3

Local Invocation

In this section, I will show you how to simulate the local invocation using CORBA. Basically, the idea is the same as behind RMI: transferring the object bytecode from the server to the client application. Still, we make the client able to rebuild the remote object locally starting from the transferred bytecode.



As you know, a compiled Java object consists of a bytecode divided into one or more class files. Indeed, to make the example simpler, I assume there is just one class file. You can implement a CORBA service transferring the class file to the client, which dynamically instances the class by using the Class.forName method. In this way, you can carry out the local execution of Java objects implemented on a remote CORBA Server.

The first step is to implement a CORBA object called ClassLoader, which allows transferring a class file from server to client. The IDL is the following:

interface ClassLoader {
  typedef sequence<octet> bytecode;
  bytecode getImplementation(in string className);
};

The ClassLoader interface defines the bytecode user type consisting of a byte sequence. It declares the getImplementation method as well, which takes a class name as a parameter and returns the associated Java bytecode. The implementation of this method searches for the file called className + ".class" on the server machine, opens this file, and returns the byte sequence of which it consists. You can implement ClassLoader like this:

import java.io.*;
import org.omg.CORBA.*;

// ClassLoader implementation
public class ClassLoaderImpl extends ClassLoaderPOA {

  // Get the java bytecode of the remote object
  public byte[] getImplementation(String className) {
    try {
      // Open the .class file
      RandomAccessFile raf = 
        new RandomAccessFile(className+".class","r");
      // Put the bytes in an array
      byte v[] = new byte[(int)raf.length()];
      raf.readFully(v);
      raf.close();
      // Return the bytes
      return v;
    }
    catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
}

The class is a CORBA object extending the ClassLoaderPOA-generated skeleton. The getImplementationmethod accesses the class file and fills the v array with the bytes coming from the file. Now you can build the ClassLoaderService CORBA server, exposing ClassLoaderImpl as follows:

import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import org.omg.PortableServer.*;
import org.omg.PortableServer.POA;
import org.omg.CosNaming.NamingContextPackage.*;

public class ClassLoaderService {

  public static void main(String args[]) throws Exception {

    // Create and initialize the ORB
    ORB orb = ORB.init(args, null);

    // Create the ClassLoader implementation    
    ClassLoaderImpl impl = new ClassLoaderImpl();

    // Activate the POAManager
    POA rootpoa = 
      POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
    rootpoa.the_POAManager().activate();

    // Get object reference from the servant
    org.omg.CORBA.Object ref = rootpoa.servant_to_reference(impl);
    ClassLoader href = ClassLoaderHelper.narrow(ref);

    // Using NameService
    org.omg.CORBA.Object objRef =
      orb.resolve_initial_references("NameService");
    NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

    // Bind the "CLASSLOADER" Object Reference in Naming
    String name = "CLASSLOADER";
    NameComponent path[] = ncRef.to_name(name);
    ncRef.rebind(path, href);

    // Server Ready
    System.out.println("CLASSLOADER SERVICE READY.");
    orb.run();

  }
}

Clients accessing ClassLoaderService obtain the CORBA object named CLASSLOADER, which is a ClassLoaderImpl instance. Using the getImplementation method, a client will be able to load any class file stored on the server machine. Then, the client can use the bytecode to locally rebuild the Java object. Finally, we need a further service that converts the bytecode in a class file, writes that file on the client machine and, using the Class.forName method, instances the object dynamically. You can make this client facility in this way:

import java.io.*;

public class ClassMaker {

  // Create a class instace starting form the bytecode
  public static Object make(String className, byte[] bytecode) {
    try {
      // Write the .class file
      RandomAccessFile raf = 
        new RandomAccessFile(className+".class","rw");
      raf.write(bytecode);
      // Instace and return the object
      return Class.forName(className).newInstance();
    }
    catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
}

The ClassMaker class contains the static method make, having as input the class name and the associated bytecode. By using Class.forName and newInstance, it returns an instance of the class behind the bytecode. Figure 1 shows the process to obtain a local copy of an object implemented by a CORBA server.


Figure 1. Obtaining a local copy of a CORBA server-implemented object.

As you may notice, the client application requires the CLASSLOADER service to obtain a local instance of MyObjectobject. The ClassLoader implementation, invoking getImplementation, searches for the MyObjectImpl.class file and converts it into a sequence of bytes. That sequence will be returned to the client application, which builds the MyObject.class file on the client machine by using ClassMaker. Eventually, the client invokes Class.forName and newInstance to create a local concrete instance of MyObject. It is very important that the MyObject interface be present in both the client and server applications. For the client, this is necessary because the make method of ClassLoader returns a generic Java object. Therefore, the client has to cast such a generic object with the right interface that is MyObject. Obviously, the interface must be present on the server side as well, because it is implemented right there.

As stated earlier, both the client application and the MyObject implementation must be developed in Java. On the contrary, ClassLoadService and ClassLoader can be written in other languages supporting IDL and CORBA. In fact, their duty is not Java-dependent -- they just allow transferring a file from the server to the client. Futher proof of this concept: I have written an IDL interface for ClassLoader but not for MyObject.

Pages: 1, 2, 3

Next Pagearrow