William Grosso, [email protected] (C) 1999, all rights reserved Basic RMI.
-
Upload
karen-carr -
Category
Documents
-
view
220 -
download
0
Transcript of William Grosso, [email protected] (C) 1999, all rights reserved Basic RMI.
![Page 2: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/2.jpg)
Remote Method InvocationBasic ExampleActivationDouble-Checked Locking Socket FactoriesSystem Properties
![Page 3: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/3.jpg)
Recall: SocketsGood
Efficient, well-understood Language/platform independent Easy to customize for security and
compressionLess Good
Not very abstract “Stream” data model isn’t very OO Relies on application-level protocol being
defined (and implemented)
![Page 4: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/4.jpg)
The VisionIf the code on both sides is Java, then
the way to send data across the wire should also “be Java”
Send messages to objects (independent of location)
Caution: In the long-run, this is a pipe dream Objects across the wire have a much
greater latency, and can fail in ways that in-process objects cannot
![Page 5: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/5.jpg)
What is RMI ?[R]emote [M]ethod [I]nvocationA way to send messages to objects
over the network Built on top of sockets Friendly and easy to use for Java
programmersAn entire framework for building
distributed applicationsInfrastructure for the really cool stuff
![Page 6: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/6.jpg)
Definition Layering
java.net
RMI
Jini
Javaspaces
![Page 7: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/7.jpg)
Implementation Layering
java.net
RMI
Jini
Javaspaces
Servlets
EJB
![Page 8: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/8.jpg)
Shared Assumptionsabout the world
Our Example
Dispatcher
Client
Client
ClientLimo
Limo
Limo
![Page 9: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/9.jpg)
Putting this on a Network
Dispatcher
Client
Client
ClientLimo
Limo
Limo
![Page 10: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/10.jpg)
Stubs and Skeletons
Dispatcher
Client
Limo
Limo Stub
Dispatcher Stub
Dispatcher SkeletonLimo Skeleton
![Page 11: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/11.jpg)
Making a Callclient clientSideStub serverSide
Skeletonserver
fooforward call along wire
foo
client "thinks" it is talking directly to server
All the arguments (and the method name) get wrapped up and sent over the wire
Skeleton unwraps everything and calls the servers implementatiof foo
![Page 12: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/12.jpg)
Basic Development ProcedureDefine InterfacesDefine Serializable Value ObjectsStop and Think about Object Identity Implement ServerImplement ClientGenerate Stubs and Skeletons Write Security Policy(Run System)
![Page 13: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/13.jpg)
Our Classes in UML
Remote
RemoteObject
UnicastRemoteObject Dispatcher Limo
DispatcherImpl LimoImpl
DriverLocationPassenger
Serializable
RemoteServer
![Page 14: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/14.jpg)
Our Main Interfacespackage grosso.rmi;import java.rmi.*;
public interface Limo extends Remote { public void setDispatcher(Dispatcher d) throws RemoteException; public Location getLocation() throws RemoteException; public boolean getIsCarryingPassenger() throws RemoteException; public boolean wantPassenger(Passenger passenger) throws RemoteException; public boolean pickupPassenger(Passenger passenger) throws RemoteException; public Driver getDriver() throws RemoteException;}
package grosso.rmi;import java.rmi.*;
public interface Dispatcher extends Remote { public Limo hailLimo(Passenger passenger) throws RemoteException; public void limoAvailable(Limo limo)throws RemoteException; public void limoUnavailable(Limo limo)throws RemoteException;}
![Page 15: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/15.jpg)
Serializable, Primitive, RemoteThe only value types referred to in the
interfaces are: Serializable objects Instances of a class that implements the
Remote interface Primitive values (byte, int, ...)
You can have non-serializable, non-remote objects in your applications. But they cannot be referred to in the code RMI will touch
![Page 16: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/16.jpg)
Serialized ObjectsAre only used as arguments to method
calls (cannot be messaged)Are sent “by value”
The RMI mechanism uses a subclass of ObjectOutputStream to serialize the instance and send it over the wire
The receiving JVM creates a duplicate of the original object using the serialized information
A single ObjectOutputStream is used per method call
![Page 17: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/17.jpg)
Remote ObjectsThe Remote interface is a marker
interface Objects which implement Remote are
“passed by reference”Typically you extend it by another
interface (declaring the server methods)
And then implement it by subclassing from UnicastRemoteObject
Remote
RemoteMethodDeclarations
LocalImpl
UnicastRemoteObject
![Page 18: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/18.jpg)
Pass by Reference ?How do you pass a pointer to an object
in another process space?You don’t. Remote objects have stubs
and skeletons. RMI serializes out the Remote object
RMI uses a subclass of ObjectOutputStreamwhich over-rides replaceObject to swap the stub in
E.g. you serialize out a stub and send it over the wire
![Page 19: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/19.jpg)
Object Identity is an IssueSuppose I callWhat happens in the server object ?
10 instances of Passenger are created They all have the same data inside them
(assuming a single-threaded client) But they are not the same object
They give different answers to hashcode and equals
Good practice is to over-ride equals and hashcode in your (immutable) value objects
for (int i = 0; i<10;i++) { limo.pickupPassenger(passenger)}
![Page 20: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/20.jpg)
Locationpublic class Location implements Serializable { private int _x; private int _y; public Location(Point p) { _x = p.x; _y = p.y; }
// more constructors, getX() and getY() defined//(but, mercifully, omitted from slide)
public boolean equals(Object object) { if (object instanceof Location) { Location location = (Location)object; return ((_x == location.getX()) && (_y == location.getY())); } return false; } public String toString(){ return ("X:" + _x +"Y:" + _y); } public int hashCode() { return toString().hashCode(); }}
![Page 21: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/21.jpg)
Passengerpublic class Passenger implements Serializable { private Location _startingLocation; private Location _destination;
public Passenger(Location startingLocation, Location destination) { _startingLocation = startingLocation; _destination = destination; }// getStartingLocation and getDestination defined but omitted
public boolean equals(Object object){ if (object instanceof Passenger ) { Passenger passenger= (Passenger)object; return ((_startingLocation.equals(passenger.getStartingLocation()))
&& (_destination.equals(passenger.getDestination()))); } return false; } public String toString() { return "Start:" + _startingLocation.toString() +
":end:" + _destination.toString(); } public int hashCode() { return toString().hashCode(); }}
![Page 22: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/22.jpg)
Basic Development ProcedureDefine InterfacesDefine Serializable Value ObjectsStop and think about object identity Implement ServerImplement ClientGenerate Stubs and Skeletons Write Security PolicyRun System
![Page 23: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/23.jpg)
Two Types of ServersNamed, universally locateable ones
Implement Remote (and extend UnicastRemoteObject)
Listed in a registry somewhere Example: DispatcherImpl
Servers that clients must be told about Implement Remote (and extend
UnicastRemoteObject) But not in listed in any registry Example: LimoImpl
![Page 24: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/24.jpg)
Distinction is not in the ServerUsually, there is some factory object,
or launching code, that knows whether a given server needs to be registered
You can’t tell from the interface, and usually can’t tell from the implementation, how a server will make itself available This is part of the “background
assumptions” which appeared on our architecture diagram
![Page 25: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/25.jpg)
NamingSimple interface to (already running)
registry Implemented via 5 static methods
public static String[] list(String name) public static Remote lookup(String name) public static void bind(String name, Remote obj) public static void rebind(String name, Remote obj) public static void unbind(String name)
![Page 26: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/26.jpg)
What’s in a NameAll the arguments to Naming take a
String with the following format: Host defaults to the local machine Port defaults to 1099 name is intended to be human readable
”Find the rmiregistry listening on [port] of [machine]. Register me there as [name].” ”Find the rmiregistry listening on [port] of
[machine]. Get me the registered oject named [name]”
//host:port/name
![Page 27: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/27.jpg)
DispatcherImplpublic class DispatcherImpl extends UnicastRemoteObject implements Dispatcher{ private ArrayList _availableLimos;
public DispatcherImpl() throws RemoteException { _availableLimos= new ArrayList(); } public Limo hailLimo(Passenger passenger) throws RemoteException{ Collections.shuffle(_availableLimos); Iterator i = _availableLimos.iterator(); while(i.hasNext()){ Limo limo = (Limo) i.next(); if (limo .pickupPassenger(passenger)){ return limo; } } return null; } public void limoAvailable(Limo limo) throws RemoteException{ if (false==_availableLimos.contains(limo)) { _availableLimos.add(limo); } } public void limoUnavailable(Limo limo) throws RemoteException{ _availableLimos.remove(limo); }}
![Page 28: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/28.jpg)
LaunchDispatcher
package grosso.rmi;import java.rmi.server.*;import java.rmi.*;
public class LaunchDispatcher { public static void main(String[] args) { System.setSecurityManager(new RMISecurityManager()); try { Dispatcher dispatcher = new DispatcherImpl(); Naming.rebind("Dispatcher ", dispatcher); } catch (Exception e){} }}
![Page 29: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/29.jpg)
LimoImplpackage grosso.rmi;import java.rmi.*;import java.rmi.server.*;
public class LimoImpl extends UnicastRemoteObject implements Limo { private boolean _havePassenger; private Dispatcher _dispatcher; private Location _currentLocation; private Driver _driver; public LimoImpl(Dispatcher dispatcher, Driver driver)
throws RemoteException { _havePassenger = false; _dispatcher = dispatcher; _driver = driver; dispatcher.limoAvailable(this); }
public Location getLocation() throws RemoteException { return _currentLocation; }
public boolean getIsCarryingPassenger() throws RemoteException { return _havePassenger; }
![Page 30: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/30.jpg)
LimoImpl IIpublic void setDispatcher(Dispatcher dispatcher) throws RemoteException{ if ((false==_havePassenger) &&(null!=_dispatcher)) { _dispatcher.limoUnavailable(this); if(null!=dispatcher){ dispatcher.limoAvailable(this); } } _dispatcher = dispatcher; }
public boolean wantPassenger(Passenger passenger) throws RemoteException { return (false ==_havePassenger); // a very simple model of
// cabbie decision making }
public Driver getDriver() throws RemoteException { return _driver; }}
![Page 31: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/31.jpg)
LimoImpl III
public boolean pickupPassenger(Passenger passenger) throws RemoteException
{ if (true==_havePassenger) { return false; } _havePassenger = true; _dispatcher.limoUnavailable(this); _currentLocation=passenger.getDestination(); _dispatcher.limoAvailable(this); return true; }}
![Page 32: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/32.jpg)
LaunchLimopublic class LaunchLimo { public static void main(String[] args) {// In reality, we'd probably do something a little cleverer // here (use more command line args or use a factory server) System.setSecurityManager(new RMISecurityManager()); try { Dispatcher dispatcher = (Dispatcher) Naming.lookup("Dispatcher");
// name bootstrap issue for (int currentTaxiDriver=0; currentTaxiDriver < args.length;
currentTaxiDriver++) { Driver driver = new Driver(args[currentTaxiDriver]); Limo currentLimo = new LimoImpl(dispatcher, driver); System.out.println("Driver " + driver.name + " is on the road"); } System.out.println("All drivers have been launched"); } catch (Exception e){} }}
![Page 33: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/33.jpg)
Registration Timing Sequence
launchLimo dispatcher registry particularLimo:LimoImpl
Naming
lookup(dispatcher)
create
add in limo
![Page 34: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/34.jpg)
SimpleClientpublic class SimpleClient extends SelfCleaningFrame{ private JTextArea _reportsBack; private JTextField _startX; private JTextField _startY; private JTextField _destinationX; private JTextField _destinationY; private JButton _hailCab;
public SimpleClient(){ // set up GUI. The key point here is that all the action is // keyed around an event on the hailcab button. }
public static void main(String[] args){ System.setSecurityManager(new RMISecurityManager()); new SimpleClient().show(); }}
![Page 35: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/35.jpg)
SimpleClientII private class ButtonAction implements ActionListener { public void actionPerformed(ActionEvent e){ try { Dispatcher dispatcher = (Dispatcher) Naming.lookup("Dispatcher"); Limo limo = dispatcher.hailLimo(getPassenger()); if (null!=limo) { Driver driver = limo.getDriver(); _reportsBack.append("Limo is driven by " + driver.name +"\n"); } else { _reportsBack.append("No limos available \n"); } } catch (Exception ee){} }
private Passenger getPassenger() { Location startingLocation = new Location(1,4); Location destination = new Location(2,5); return new Passenger(startingLocation, destination); } }
![Page 36: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/36.jpg)
Method Call Timing Sequence
client Naming dispatcher limo
lookup
hailLimo
pickup passenger
returns limo
![Page 37: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/37.jpg)
Generating Stubs / SkeletonsRMIC -- [RMI] [C]ompilerAutomatically builds stubs and
skeletons from .class files of server implementations“rmic -d outputpath fully.qualified.class.name”
![Page 38: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/38.jpg)
Running The Current System
start java -Djava.security.policy=java.policy grosso.rmitalk.LaunchLimo Bob Al Fred Kerry
Start the registry going
Launch the Dispatcher
Launch the Limos
Run the Client App
start rmiregistry
start java -Djava.security.policy=java.policy grosso.rmi.LaunchDispatcher
java -Djava.security.policy=java.policy grosso.rmi.SimpleClient
![Page 39: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/39.jpg)
SimpleClient
![Page 40: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/40.jpg)
What We didDefine InterfacesDefine Serializable Value ObjectsStop and think about object identity Implement ServerImplement ClientGenerate Stubs and Skeletons Write Security PolicyRun System
We’ll talk about this another day
![Page 41: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/41.jpg)
Homework Make this a multi-threaded applicationStart with dispatcher-- should be able
to handle multiple requests Limos will have to be able to handle
multiple simultaneous requests as wellBe efficient ! Synchronizing pickupPassenger()
is not a good idea
You may need to be careful with limoAvailable() / limoUnavailable() as well
![Page 42: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/42.jpg)
Making Things More SecureSo what we’ve been talking about is a
way for objects to be transparently made persistent
This involved Sending serialized object states over the wire Lots of reflection The occasional loading of bytecode from
serversWe didn’t really discuss this because only so
much fits in an overview. But part of the magic is that class definitions travel across the wire too
![Page 43: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/43.jpg)
Socket FactoriesOne way to make things more secure
is not to use the standard (“cleartext”) sockets.
Fortunately, this is really easy to do Simply write the socket factory objects And rewrite the constructor in the server
objects that will use the custom sockets
![Page 44: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/44.jpg)
The Factories
public class ClientSocketFactory implements RMIClientSocketFactory, Serializable { public Socket createSocket(String host, int port) throws IOException { return new CompressingSocket(host, port); }}
public class ServerSocketFactory implements RMIServerSocketFactory, Serializable{ public ServerSocket createServerSocket(int port) throws IOException { return new CompressingServerSocket(port); } }
![Page 45: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/45.jpg)
Changing Dispatcher
public class DispatcherImpl extends UnicastRemoteObject implements Dispatcher { private ArrayList _availableLimos;
public DispatcherImpl() throws RemoteException { super(0, new ClientSocketFactory(), new ServerSocketFactory()); _availableLimos= new ArrayList();// binding to registry happens in Factory code }
public Limo hailLimo(Passenger passenger) throws RemoteException{ Collections.shuffle(_availableLimos); Iterator i = _availableLimos.iterator(); while(i.hasNext()) {
![Page 46: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/46.jpg)
Why are the Factories Serializable ?When a connection is made,
Naming.lookup is called
The factory is serialized and downloaded to the registry and, from there, to the client
This is actually a little tricky-- you have to relax the security policy at the registry for this to work
Dispatcher dispatcher = (Dispatcher) Naming.lookup("Dispatcher");
![Page 47: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/47.jpg)
Security Policy Teaser
grant { permission java.net.SocketPermission ":0-", "accept,connect,listen";};
![Page 48: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/48.jpg)
Useful System PropertiesSystem Property Values Usage Noteshttp.proxyHost internet address Set on the client side, to let RMI know that HTTP
tunneling is available (from the internet addresslisted). What will happen is that RMI will attempt tomake connections in the normal way. If that fails, itwill attempt to use HTTP tunnelling to send themessage. This usually winds up devolving to
http://internetaddress:80/java-rmi.cgi?port=xxx?arg1=value1?....
java.rmi.dgc.leaseValue number of milliseconds How long is a default lease for ?
java.rmi.server.hostname internet address The issue here is—how does RMI figure out wherethe server is. Which starts out life as “how does theserver figure out where it is ?”This used to be a call to a naming server, but waschanged in JDK1.1 to be a native call instead. Saidnative call can sometimes return the wrong answer(e.g. an unqualified host name).
If you set this property, RMI will use this valueinstead of the value the server returns.
java.rmi.server.useLocalHostname true, false Setting this to true (it defaults to false) and no valuefor java.rmi.server.hostname will force RMI to use afully qualified hostname obtained from a nameservice.
java.rmi.server.codebase url Set on servers. This allows clients to download theclass definitions (e.g. bytecode) on the fly. The wayRMI does this is: First: Check the local classpath Second: Use contextual classpath (e.g. codebase tag in applets) Third: Use the url indicated by this flag.
![Page 49: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/49.jpg)
Useful System PropertiesSystem Property Values Usage Notes
java.rmi.server.logCalls true, false Defaults to false. If true, all calls to remote objectswill be logged in a log file. For greater control overthe log file, use RemoteServer’s getLog() andsetlog(...) methods.
Activation sets this to true for the VMs it launches.java.security.policy filesun.rmi.transport.connectionTimeout number of milliseconds How long before an attempt to connect will timeout
.(SUN specific)sun.rmi.server.activation.debugExec true, false When Activation launches a VM, this prints out all
the parameters used. Can be handy for spotting aconfiguration error. (SUN specific)
![Page 50: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/50.jpg)
Advanced Questions
Why does rmic require an implementation rather than an interface to generate stubs and skeletons ?
Server objects can support multiple interfaces, but only have one skeleton/stub pair.
Doing things this way allows reflective calls to succeed on the client side. E.g. the stub has all the information that is necessary to determine whether or not a server implements a particular interface (otherwise using instanceof or other forms of reflection would require a round-trip across the wire)
AA
![Page 51: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/51.jpg)
ReferencesThe RMI FAQ:
http://java.sun.com/products/jdk/rmi/faq.html
Archives of the RMI mailing list
http://archives.java.sun.com/archives/rmi-users.html
The RMI Specification
http://java.sun.com/products/jdk/1.2/docs/guide/rmi/spec/rmiTOC.doc.html
![Page 52: William Grosso, grosso@pacbell.net (C) 1999, all rights reserved Basic RMI.](https://reader036.fdocuments.in/reader036/viewer/2022062304/56649e845503460f94b856c0/html5/thumbnails/52.jpg)