Ein entferntes Objekt (remote object) ist ein Objekt, dessen Methoden von einer anderen Java Virtual Machine aus aufgerufen werden koennen. Ein solches Objekt wird durch ein oder mehrere entfernte Schnittstellen (remote interfaces) beschrieben.Unter Remote Method Invocation versteht man den Aufruf einer Methode eines entfernten Objektes. Der Methodenaufruf auf einem entfernten Objektes folgt dabei derselben Syntax wie der Aufruf einer lokalen Methode.
public interface Server extends Remote {
public void store(Person p) throws RemoteException; public void delete(Person p) throws RemoteException; public Vector getAll() throws RemoteException; } |
public class ServerImpl extends UnicastRemoteObject
implements Server {
private Vector persons; //stores all datasets public ServerImpl() throws RemoteException { super(); persons=new Vector(); } public synchronized void store(Person p) throws RemoteException { //add person p to the database //if p already exists update dataset int pos=persons.indexOf(p); if (pos == -1) { persons.addElement(p); } else { persons.setElementAt(p,pos); } } public synchronized void delete(Person p) throws RemoteException { //remove person p from the database //if p does not exist do nothing persons.removeElement(p); } public synchronized Vector getAll() throws RemoteException { //return a whole copy of the database //do not care about performance ;) return persons; } } |
public static void main(String[] args) {
System.setSecurityManager(new RMISecurityManager()); try { //create
the implementation object
|
public class Client {
Server serverRef; //remote reference to the server public Client(Server serverRef) { this.serverRef=serverRef; ... } void store(String name, String firstName, String eMail) { try { //create new person and store it Person p=new Person(name,firstName,eMail); serverRef.store(p); } catch (RemoteException e) { handleRemoteException(e); } } void delete(String name, String firstName) { try { //create person object for lookup //and delete it Person p=new Person(name,firstName,null); serverRef.delete(p); } catch (RemoteException e) { handleRemoteException(e); } }
public static void main(String[]
args) {
} catch
(Exception e) {
|
Klassen, welche bei Methodenaufrufen als Parameter oder Rueckgabewerte dienen, koennen bei Bedarf von per URL (http, ftp, file) automatisch nachgeladen werden.-> Server kann Aufgaben erledigen, welche zur Compile- oder Startzeit noch gar nicht definiert waren
Anwendungsbeispiel:
// Remote interface for a server that can execute different tasks.
public interface ComputeServer extends Remote {public Object executeTask(Task t) throws RemoteException;
}
// A task has to implement this interface.
// Its code is described in the execute() method.
public interface Task extends Serializable {public Object execute();
}
Aktivierung und Shutdown von Remote Objects bei Bedarf-> effiziente Ressourcennutzung
rmibase/ActivatableServerImpl.java
public class ActivatableServerImpl extends Activatable implements Server {
private Vector persons; //stores all datasets
public ActivatableServerImpl(ActivationID id, MarshalledObject data)
throws RemoteException {
super(id,0);
persons=new Vector();
}
public synchronized void store(Person p) throws RemoteException { ... }
public synchronized void delete(Person p) throws RemoteException { ... }
public synchronized Vector getAll() throws RemoteException { ... }
public static void main(String[] args) {
System.setSecurityManager(new RMISecurityManager());try {
// Properties that replaces rmid's system properties
Properties props=new Properties();
props.setProperty("java.security.policy","file:rmibase/policy.txt");
// Create an ActivationGroupDesc that contains all information
// that rmid will require
ActivationGroupDesc.CommandEnvironment ace = null;
ActivationGroupDesc exampleGroup = new ActivationGroupDesc(props, ace);
// Once the ActivationGroupDesc has been created, register it
// with the activation system to obtain its ID
ActivationGroupID agi =
ActivationGroup.getSystem().registerGroup(exampleGroup);
// Now explicitly create the group
ActivationGroup.createGroup(agi, exampleGroup, 0);
// Codebase
String location = "file:./";
// Create the rest of the parameters that will be passed to
// the ActivationDesc constructor
MarshalledObject data = null;
// The second argument to the ActivationDesc constructor will be used
// to uniquely identify this class; it's location is relative to the
// URL-formatted String, location.
ActivationDesc desc =
new ActivationDesc ("rmibase.ActivatableServerImpl", location, data);
// Create an remote instance
// Register the activation decriptor with rmid
Server server = (Server)Activatable.register(desc);// Bind the interface in the RMI registry
Naming.rebind("EMailBase",server);
} catch (Exception e) {
System.err.println("activation setup failed");
System.exit(1);
}System.exit(0);
}
}
Normalerweise versucht RMI direkte TCP Verbingungen zu entfernten Objekten aufzubauen. Firewalls erlauben dies nicht.-> Einbettung des RMI Aufrufs in einen HTTP-POST Request, Antwort im Body des HTTP Responses
2 Varianten:
- HTTP Proxy kann Requests direkt an RMI Server Port weiterleiten. -> RMI Server Socket versteht RMI Calls in HTTP-POST Requests und beantwortet diese.
- HTTP Proxy forwarded nur zu bestimmten Ports (z.B. Port 80). -> CGI Skript auf Zielmaschine wird RMI Calls an RMI Server Socket weiterleiten.
© 1998 sven.buergel@informatik.tu-chemnitz.de |