Remotes inside Serializable Objects

A serializable object can contain remote implementation objects. For simple transient objects (non POA case) the ORB runtime automatically converts these remote implementation objects into corresponding stubs before marshaling them out. In this example we will return a Vector from the server to the client that will contain references for several objects that satisfy a query.

Note: When the Portable Object Adapter is used, the ORB cannot automatically convert the remote object to an object reference because it cannot determine which POA instance to use to create the object reference. Hence when using POA with RMI, you should convert the servants (if any) inside value objects to object references before passing the value object on a remote method call.

Accounts Interface

The Accounts interface with a getDelinquentAccounts method on it that returns a Vector containing Account objects.

package obvRemote;
                                                                           
import java.util.Vector;
                                                                           
import java.rmi.Remote;
import java.rmi.RemoteException;
                                                                           
public interface Accounts extends Remote
{
    Vector getDelinquentAccounts() throws RemoteException;
}

Account Interface

The Account interface with a getBalance and getAccountNumber methods on it.

package obvRemote;
                                                                           
import java.rmi.Remote;
import java.rmi.RemoteException;
                                                                           
public interface Account extends Remote
{
    double getBalance() throws RemoteException;
                                                                           
    int getAccountNumber() throws RemoteException;
}

Accounts Implementation

The AccountsImpl maintains a collection of all the Account implementation objects. When asked for delinquent accounts, it scans the collection for accounts with a negative balance and returns them as a vector.

package obvRemote;
                                                                           
import java.util.Vector;
                                                                           
import java.rmi.Remote;
import java.rmi.RemoteException;
                                                                           
import javax.rmi.PortableRemoteObject;
                                                                           
public class AccountsImpl extends PortableRemoteObject implements Accounts
{
    private Vector _accounts = new Vector();
                                                                           
    AccountsImpl() throws RemoteException {}
                                                                           
    public synchronized Vector getDelinquentAccounts() throws RemoteException
    {
    |   Vector result = new Vector();
    |                                                                      
    |   for (int i=0; i < _accounts.size(); i++) {
    |   |   Account account = (Account) _accounts.elementAt(i);
    |   |   if (account.getBalance() < 0) 
    |   |       result.addElement(account);
    |   }
    |                                                                      
    |   return result;
    }
                                                                           
    synchronized void addAccount(Account account)
    {
    |   _accounts.addElement(account);
    }
}

Account Implementation

The AccountImpl class implements the getBalance and getAccountNumber methods.

package obvRemote;
                                                                           
import java.rmi.Remote;
import java.rmi.RemoteException;
                                                                           
import javax.rmi.PortableRemoteObject;
                                                                           
public class AccountImpl extends PortableRemoteObject implements Account
{
    private int    _acctNumber;
    private double _balance;
                                                                           
    AccountImpl(int acctNumber, double balance) throws RemoteException
    {
    |   _acctNumber = acctNumber;
    |   _balance    = balance;
    }
                                                                           
    public double getBalance() throws RemoteException
    {
    |   return _balance;
    }
                                                                           
    public int getAccountNumber() throws RemoteException
    {
    |   return _acctNumber;
    }
}

Accounts Server

package obvRemote;
                                                                           
import util.Util;
                                                                           
import java.util.Date;
                                                                           
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
    |   |   AccountsImpl accounts = new AccountsImpl();
    |   |                                                                  
    |   |   // add accounts to the accounts
    |   |   accounts.addAccount(new AccountImpl(1001,  197.45));
    |   |   accounts.addAccount(new AccountImpl(1002,  389.34));
    |   |   accounts.addAccount(new AccountImpl(1003, -302.17));
    |   |   accounts.addAccount(new AccountImpl(1004, -233.03));
    |   |                                                                  
    |   |   // create a stringified object reference
    |   |   String accountsIOR = orb.object_to_string((Object) 
    |   |       PortableRemoteObject.toStub(accounts));
    |   |                                                                  
    |   |   // write the stringified object reference
    |   |   Util.writeIOR(accountsIOR, "ior", true);
    |   |                                                                  
    |   |   // wait for invocations
    |   |   System.out.println("waiting for invocations ...");
    |   |                                                                  
    |   } catch (Exception ex) {
    |   |   ex.printStackTrace();
    |   }
    }
}

Accounts Client

The client gets the Accounts object and then gets the delinquent objects as a vector, which contains object references to Account objects.

package obvRemote;
                                                                           
import util.Util;
                                                                           
import org.omg.CORBA.ORB;
                                                                           
import java.util.Vector;
                                                                           
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 accountsIOR = Util.readIOR("ior");
    |   |                                                                  
    |   |   // narrow the stringified object
    |   |   Accounts accounts = (Accounts) orb.string_to_object(accountsIOR);
    |   |                                                                  
    |   |   // get the stocks held by the portfolio
    |   |   Vector delinquent = accounts.getDelinquentAccounts();
    |   |   for (int i=0; i < delinquent.size(); i++) {
    |   |   |   Account account = (Account) delinquent.elementAt(i);
    |   |   |   PortableRemoteObject.connect(account, accounts);
    |   |   |   System.out.println("account: " + account.getAccountNumber() + 
    |   |   |       " balance: " + account.getBalance());
    |   |   }
    |   |                                                                  
    |   } catch (Exception ex) {
    |   |   ex.printStackTrace();
    |   }
    }
}


Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.