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 Stack



In this section, I will develop an example representing a client application that obtains a copy of a remote stack object by using the ClassLoaderSevice service and ClassMaker. The first step is writing the Java interface for the Stack:

public interface Stack {
  public void push(short value);
  public short pop();
}

Then, you can implement that interface on the CORBA server in this manner:

import java.util.ArrayList;

public class StackImpl implements Stack {

  private ArrayList _s = new ArrayList();

  public synchronized void push(short value) {
    System.out.println("Push: " + value);
    _s.add(new Short(value));
  }

  public synchronized short pop() {
    if (_s.size()==0) return -1;
    short value = ((Short)_s.get(_s.size()-1)).shortValue();
    _s.remove(_s.size()-1);
    System.out.println("Pop: " + value);
    return value;
  }
}

After compiling StackImpl, you can find on the server machine the StackImpl.class file. A client application that wants to obtain a local instance of StackImpl has to make a connection to ClassLoaderService service for getting a ClassLoader implementation. Then, invoking getImplementation, it receives the bytecode of the StackImpl object (which is stored in StackImpl.class). Finally, the client application can build a local instance of StackImpl by using the ClassMaker class.

You can delegate the details about the creation of the Stack instances to a factory, as shown in this code:

public class StackFactoryClient {

  private ClassLoader _loader = null;

  // Set the loader instance
  public StackFactoryClient(ClassLoader loader) {
    _loader = loader;
  }

  // Return a local instance of StackImpl
  public Stack getLocalStack() {
    // Use the ClassLoader service
    byte bytecode[] = _loader.getImplementation("StackImpl");
    // Make the object
    return (Stack) ClassMaker.make("StackImpl",bytecode);
  }
}

The constructor of the StackFactoryClient class takes as the input parameter a ClassLoader object, which represents a reference to the active implementation of ClassLoaderImpl, which is the distributed object named CLASSLOADER. That reference will be assigned to the _loader attribute. The factory contains the getLocalStack method, calling the _loader.getImplementation("StackImpl") method and returning the instance of StackImpl built by ClassMaker. By means of StackFactoryClient, each client application can get a local instance of a distributed Stack object.

At this point, you are ready to implement a simple client application obtaining a local stack implementation by using the ClassLoader service. The code is this:

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

public class StackClient {

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

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

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

    // Resolve the Object Reference in Naming
    String name = "CLASSLOADER";
    ClassLoader loader =
      ClassLoaderHelper.narrow(ncRef.resolve_str(name));

    // Stack Factory
    StackFactoryClient factory = new StackFactoryClient(loader);

    // Create a local Stack Reference
    Stack stack = factory.getLocalStack();

    // Push (local invocation);
    stack.push((short)5);

    // Pop (local invocation);
    short val = stack.pop();

  }
}

The loader variable represents the Java reference of the CLASSLOADER distributed object. The program creates an instance of StackFactoryClient by passing loader as a parameter of the constructor. Then, getLocalStack returns the local instance of Stack, which is stored in the stack variable. Here, push and pop work on the client virtual machine, hence the output:

Push: 5
Pop: 5

will be shown in the client console.

Limitations

The explained strategy presents some limitations. First, client and server applications must be written in Java. Second, the bytecode of a class is not always held in one class file. For the StackImpl class, it was just one class file, but in other complex situations this is not always true, especially when there are inner classes. If you need ClassLoaderImpl to work properly even in those cases, you must change the implementation in order to support multi-file transfer. A very efficient solution might be to archive the class files into a single jar and transfer it. Using this approach, you have to provide that the CLASSPATH environment variable references this jar file.

This proposed solution doesn't deal with packages. In the previous examples, I didn't use package names for the classes. When a class belongs to a package, it is placed in a directory that has the same name as the package. Therefore, the ClassLoaderService should be modified in order to search for the class file on the right server directory and transfer it to the same client directory. To fix this, you can use a jar file, as well. In this manner, the transferred file will be a single jar and, as you know, the name of the package is specified just inside of it.

Conclusion

Obtaining a local instance of distributed CORBA objects may be useful in some circumstances. Suppose you want to provide a CORBA service to run a heavy algorithm requiring many CPU hours. If this component is a Web service, a thousand applications could make a connection with it. In this case, the host machine could be so busy that it couldn't satisfy all requirements efficiently. To avoid that, you can let the service return not the result of the elaboration but the code of the algorithm, which will be executed on the client machine. You can do this using the pass-by-value strategy as I have mentioned. Hence, such a CORBA server will be a class provider and not, as usually is the case, an object provider.

You should note, however, that the latest CORBA 2.3 now supports the object-by-value; therefore, you can carry it out in java by RMI-IIOP.

Bibliography

Q. Mahmoud, "CORBA Programming with J2SE 1.4." java.sun.com, May 2002.

Giuseppe Naccarato has a degree in computer science and works as software developer for an IT company based in Glasgow (UK). His main interests are J2EE- and .Net-related technologies. Contact Giuseppe at http://www.giuseppe-naccarato.com.


Return to ONJava.com.