 |
CS 696 Emerging Technologies: Distributed Objects |
|
|---|
Spring Semester, 1998
RMI Parameters
To Lecture Notes Index
© 1998, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 21-Apr-98
Contents of Doc 7, RMI Parameters
- References
- Parameters
- Pass-by-Value (copy) verse Pass-by-Reference
- Parameters and Remote Objects
- Parameters and RMI
- A Simple Example
- Trouble in RMI Land - Passing Foo
- Parameter Passing in Remote Method Invocation
Java Remote Method Invocation Specification, section 2.6
public class Foo
{
public void method( Object parameter )
{
result = parameter.someMethod( echo );
}
}
Pass-by-Value
(Copy)
- A copy of the parameter is made
-
- The method receives and acts on the copy
Pass-by-Reference
- The method receives a reference to the parameter
-
- The method uses the reference to access the parameter, which is held by the
caller
public class Foo
extends UnicastRemoteObject
implements FooRemote
{
public void remoteMethod( Object parameter )
{
result = parameter.someMethod( echo );
}
}
If Foo is a server (remote) object on machine A and
If a client object on machine B calls Foo's remoteMethod
How to handle passing the parameter to the method?
Option 1 Pass-by-value
Send a copy of the parameter to machine A
This requires sending all of the parameters fields, and the fields of the
fields, etc. to machine A


Option 2 Pass-by-reference
Send a reference of the parameter to machine A
This means that "parameter.someMethod( echo )" results in sending a request to
machine B over the network to perform "someMethod" on the parameter
If someMethod( echo ) access "echo" then that results in a request over the
network to perform a method call on echo

In RMI objects that implement the Remote interface are passed by reference
All other parameters are passed by copy
Client passes a vector to the server,
Server adds a string to the vector
Server returns the vector
package whitney.rmi.examples.basic;
import java.util.Vector;
public interface VectorParameter extends java.rmi.Remote
{
public Vector modify( Vector input )
throws java.rmi.RemoteException;
}
The Server
package whitney.rmi.examples.basic;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.Registry;
import java.util.Vector;
import sdsu.rmi.registry.Registrar;
import sdsu.util.ProgramProperties;
import java.io.IOException;
public class VectorParameterServer
extends UnicastRemoteObject
implements VectorParameter
{
public VectorParameterServer() throws RemoteException {}
public Vector modify( Vector input ) throws RemoteException
{
input.addElement( "Hi Mom");
return input;
}
public static String RMI_NAME = "cs696/VectorParameter";
static String serverClass =
"whitney.rmi.examples.basic.VectorParameterServer";
public static void main(String args[]) throws
RemoteException, IOException
{
int port = getPort( args );
String nameList =
Registrar.verboseRebind( port,
RMI_NAME, serverClass);
System.out.println( nameList );
}
private static int getPort( String args[] ) throws IOException
{
ProgramProperties flags = new ProgramProperties( args );
int defaultPort = Registry.REGISTRY_PORT;
int port = flags.getInt( "p", defaultPort );
return port;
}
}
The Client
package whitney.rmi.examples.basic;
import java.rmi.*;
import java.rmi.registry.Registry;
import java.net.MalformedURLException;
import java.io.IOException;
import java.util.Vector;
import sdsu.util.ProgramProperties;
public class VectorParameterClient
{
public static void main(String args[])
{
try
{
String serverLabel =
VectorParameterServer.RMI_NAME;
String server = getServerURL( args, serverLabel );
VectorParameter remote =
(VectorParameter) Naming.lookup( server );
Vector data = new Vector();
Vector remoteData = remote.modify( data );
System.out.println( "remote " + remoteData);
System.out.println( "local " + data);
if ( data == remoteData )
System.out.println( "equal" );
else
System.out.println( "not equal" );
}
catch ( Exception error)
{ error.printStackTrace(); }
}
private static String getServerURL( String args[],
String serverLabel )
throws IOException
{
String hostKey = "h";
String portKey = "p";
ProgramProperties flags = new ProgramProperties( args );
String host = null;
if ( flags.containsKey( hostKey ) )
host = flags.getString( hostKey );
else
{
System.out.println( "Missing flag " + hostKey );
System.exit( 0 );
}
int defaultPort = Registry.REGISTRY_PORT;
int port = flags.getInt( portKey, defaultPort );
return "rmi://" + host + ":" + port + "/" + serverLabel;
}
}
The Output of the Client
remote [Hi Mom]
local []
not equal
Foo
package whitney.rmi.examples.basic;
public class Foo
{
String name = "Roger";
}
Remote Interface
package whitney.rmi.examples.basic;
public interface ParameterTrouble extends java.rmi.Remote
{
public void tryMe( Foo input ) throws
java.rmi.RemoteException;
}
Server
package whitney.rmi.examples.basic;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.Registry;
import sdsu.rmi.registry.Registrar;
import sdsu.util.ProgramProperties;
import java.io.IOException;
public class ParameterTroubleServer
extends UnicastRemoteObject
implements ParameterTrouble
{
public ParameterTroubleServer() throws RemoteException {}
public void tryMe( Foo input ) throws RemoteException
{}
public static String RMI_NAME = "cs696/ParameterTrouble";
static String serverClass =
"whitney.rmi.examples.basic.ParameterTroubleServer";
public static void main(String args[]) throws RemoteException, IOException
{
int port = getPort( args );
String nameList = Registrar.verboseRebind( port, RMI_NAME, serverClass);
System.out.println( nameList );
}
private static int getPort( String args[] ) throws IOException
{
ProgramProperties flags = new ProgramProperties( args );
int defaultPort = Registry.REGISTRY_PORT;
int port = flags.getInt( "p", defaultPort );
return port;
}
}
Passing Foo Client
package whitney.rmi.examples.basic;
import java.rmi.*;
import java.rmi.registry.Registry;
import java.net.MalformedURLException;
import java.io.IOException;
import sdsu.util.ProgramProperties;
public class ParameterTroubleClient
{
public static void main(String args[])
{
try
{
String serverLabel =
ParameterTroubleServer.RMI_NAME;
String server = getServerURL( args, serverLabel );
ParameterTrouble remote =
(ParameterTrouble) Naming.lookup( server );
remote.tryMe( new Foo() );
}
catch ( Exception error)
{
error.printStackTrace();
}
}
private static String getServerURL( String args[], String serverLabel ) throws IOException
{
String hostKey = "h";
String portKey = "p";
ProgramProperties flags = new ProgramProperties( args );
String host = null;
if ( flags.containsKey( hostKey ) )
host = flags.getString( hostKey );
else
{
System.out.println( "Missing flag " + hostKey );
System.exit( 0 );
}
int defaultPort = Registry.REGISTRY_PORT;
int port = flags.getInt( portKey, defaultPort );
return "rmi://" + host + ":" + port + "/" + serverLabel;
}
}
Output
java.rmi.MarshalException: Error marshaling arguments; nested exception is:
java.io.NotSerializableException: whitney.rmi.examples.basic.Foo
at java.lang.Throwable.<init>(Compiled Code)
at java.lang.Exception.<init>(Compiled Code)
at java.io.IOException.<init>(Compiled Code)
at java.rmi.RemoteException.<init>(Compiled Code)
at java.rmi.MarshalException.<init>(Compiled Code)
at whitney.rmi.examples.basic.ParameterTroubleServer_Stub.tryMe(Compiled
Code)
at whitney.rmi.examples.basic.ParameterTroubleClient.main(Compiled Code)
An argument to, or a return value from, a remote object can be any Java type
that is serializable
An argument to, or a return value, a remote object can also be a remote object,
but the declared type must be a Remote interface
Note, the remote object may return an implementation of a remote object, but
only stub is received
Remote Example
The Interface
public interface RemoteParameter extends java.rmi.Remote
{
public RemoteParameter itWorks( ) throws
java.rmi.RemoteException;
}
The Client (parts missing)
public class RemoteParameterClient
{
public static void main(String args[])
{
try
{
String serverLabel =
RemoteParameterServer.RMI_NAME;
String server = getServerURL( args, serverLabel );
RemoteParameter remote =
(RemoteParameter) Naming.lookup( server );
RemoteParameter aReference = remote.itWorks( );
System.out.println( "It Works");
} catch ( Exception error) {}
}
The Server (parts missing)
public class RemoteParameterServer
extends UnicastRemoteObject
implements RemoteParameter
{
public RemoteParameter itWorks( ) throws RemoteException
{
return this;
}
visitors since 05-Feb-98