The ORB compilers and runtime provide standard support for passing Java
objects by-value. An argument to, or a return value from, a remote object
can be any Java type that is serializable. This includes Java primitive
types, and Java objects that implement the java.io.Serializable
interface.
In this example we will ask a remote object for its meta-data object.
Using the meta-object's remote interface we will set/get arbitrary
serializable java.lang.Object
s as properties.
package metaData; public interface Component extends java.rmi.Remote { MetaData getMetaData() throws java.rmi.RemoteException; }
package metaData; import java.util.Enumeration; import java.rmi.RemoteException; /** The MetaData emulates the java.util.Dictionary interface. */ public interface MetaData extends java.rmi.Remote { // returns the number of keys int size() throws RemoteException; // tests if there is currently no keys boolean isEmpty() throws RemoteException; // get the value for the given key Object get(Object key) throws RemoteException; // put the value with the given key Object put(Object key, Object value) throws RemoteException; // remove the key and its corresponding value Object remove(Object key) throws RemoteException; // get the enumeration of keys Enumeration keys() throws RemoteException; // get the enumeration of values Enumeration elements() throws RemoteException; }
Notice that several MetaData
methods have plain
java.lang.Object
in their signatures. It is the
programmer's responsibility to pass a java.io.Serializable
object at runtime. Otherwise, the ORB will throw a class cast or marshalling
exception. Of course, we could have made the signatures type specific. For
example, we could have restricted the key
above to always be a
java.lang.String
.
package metaData; import java.rmi.RemoteException; import javax.rmi.PortableRemoteObject; public class ComponentImpl extends PortableRemoteObject implements Component { private MetaData _metaData; ComponentImpl() throws RemoteException { | _metaData = new MetaDataImpl(); } public MetaData getMetaData() throws RemoteException { | return _metaData; } }
We will use the standard java.util.Hashtable
for implementing the meta data. Notice that since the Hashtable's
enumerator is not Serializable, we will need to write our own version.
package metaData; import java.io.Serializable; import java.rmi.RemoteException; import javax.rmi.PortableRemoteObject; import java.util.Hashtable; import java.util.Enumeration; public class MetaDataImpl extends PortableRemoteObject implements MetaData { private Hashtable _metaData; MetaDataImpl() throws RemoteException { | _metaData = new Hashtable(); } public int size() throws RemoteException { | return _metaData.size(); } public boolean isEmpty() throws RemoteException { | return _metaData.isEmpty(); } public Object get(Object key) throws RemoteException { | return _metaData.get(key); } public Object put(Object key, Object value) throws RemoteException { | return _metaData.put(key, value); } public Object remove(Object key) throws RemoteException { | return _metaData.remove(key); } public Enumeration keys() throws RemoteException { | synchronized (_metaData) { | | return new MetaDataEnumerator(_metaData.keys(), size()); | } } public synchronized Enumeration elements() throws RemoteException { | synchronized (_metaData) { | | return new MetaDataEnumerator(_metaData.elements(), size()); | } } } class MetaDataEnumerator implements Enumeration, Serializable { private int _cursor; private Object[] _elements; MetaDataEnumerator(Enumeration e, int size) { | _elements = new Object[size]; | | int i=0; | while (e.hasMoreElements()) { | | _elements[i++] = e.nextElement(); | } | | _cursor = 0; } public boolean hasMoreElements() { | return _cursor != _elements.length; } public Object nextElement() { | return _elements[_cursor++]; } }
The server creates the ORB, creates a Java RMI servant, writes out it's
stringified object reference, and then waits for invocations. Notice, that
since HelloImpl
is not a CORBA object (does not implement
org.omg.CORBA.Object,) you need to first get its stub/object reference
before using the object_to_string
method.
package metaData; import util.Util; import org.omg.CORBA.ORB; import org.omg.CORBA.Object; import javax.rmi.PortableRemoteObject; public class Server { public static void main(String[] args) { | try { | | | | // create the jBroker ORB | | ORB orb = ORB.init(args, null); | | | | // create a servant | | Component component = new ComponentImpl(); | | | | // create a stringified object reference | | String ior = orb.object_to_string((Object) PortableRemoteObject. | | toStub(component)); | | | | // write the stringified object reference | | Util.writeIOR(ior, "ior", true); | | | | // wait for invocations | | System.out.println("waiting for invocations ..."); | | orb.run(); | | | } catch (Exception ex) { | | ex.printStackTrace(); | } } }
The client creates the ORB, reads the stringified object reference of
the Component
object, and casts it to the Component
type.
It then gets the MetaData
interface from the Component
and sets and gets meta data on it.
Notice, that java.lang.String
and the
java.util.Vector
are JDK classes
that are already Serializable. The Enumeration
is the Serializable object that we wrote in the above section.
package metaData; import util.Util; import org.omg.CORBA.ORB; import java.util.Vector; import java.util.Enumeration; import javax.rmi.PortableRemoteObject; public class Client { public static void main(String[] args) { | try { | | | | // create the jBroker ORB | | ORB orb = ORB.init(args, null); | | | | // read the stringified object reference | | String ior = Util.readIOR("ior"); | | | | // narrow the stringified object | | Component component = (Component) orb.string_to_object(ior); | | | | // get the component's meta-data interface | | MetaData metaData = component.getMetaData(); | | | | // add lifecycle and timeout meta data | | metaData.put("lifecycle", "transient"); | | metaData.put("timeout", new Integer(5000)); | | | | // set the access control list (ACL) | | Vector acl = new Vector(); | | acl.addElement("user1"); | | acl.addElement("user2"); | | metaData.put("acl", acl); | | | | // enumerate the meta data keys | | System.out.print("Component Keys: "); | | Enumeration keys = metaData.keys(); | | while (keys.hasMoreElements()) { | | | System.out.print(keys.nextElement() + ", "); | | } | | System.out.println(); | | | | // print out the Component ACL | | System.out.print("Component ACL : "); | | acl = (Vector) metaData.get("acl"); | | for (int i=0; i < acl.size(); i++) { | | | System.out.print(acl.elementAt(i) + ((i==(acl.size()-1)) ? | | | "\n" : ", ")); | | } | | | } catch (Exception ex) { | | ex.printStackTrace(); | } } }
Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.