java rmi: remote method invocationdisys/rmi.pdf · rmi, deve essere dichiarata come tale indicando...

20
1 Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari Java RMI I lucidi che seguono sono stati prodotti sulla base dei seguenti riferimenti: - Sistemi Distribuiti Dip. Informatica Università di Bari (S.Pizzutilo) - Seminario Java RMI di G.Cozzolongo Java RMI: Remote Method Invocation Java Remote Method Invocation (RMI) è l’implementazione Java del modello ad oggetti distribuiti E’ un meccanismo che consente ad un oggetto su un JVM di invocare metodi di oggetti residenti in altre JVM La sintassi per le invocazioni remote è esattamente la stessa di quella delle invocazioni locali Possono essere passati argomenti, calcolati nel contesto della macchina chiamante Possono essere restituiti valori, calcolati nel contesto della macchina remota Gli elementi chiave sono serializzazione e dynamic class loading Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari Remote Method Invocation Perche RMI? L’obiettivo è di permettere ad una applicazione in esecuzione su una macchina locale di invocare i metodi di un oggetto in esecuzione su un altro computer. Si definisce client il programma chiamante che ottiene riferimento all’oggetto remoto, server il programma che crea gli oggetti remoti. Tali applicazioni sono anche denominate distributed object application • miglioramento delle prestazione complessive • semplicità nella gestione delle risorse distribuite • incremento della potenza operativa es: suddivisione di una computazione pesante in procedure più piccole, eseguite tutte su macchine diverse diminuendo in tal modo il tempo complessivo di esecuzione Quali vantaggi? Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Upload: others

Post on 31-May-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

1

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Java RMI

I lucidi che seguono sono stati prodotti sulla base dei seguenti riferimenti: -  Sistemi Distribuiti Dip. Informatica Università di Bari (S.Pizzutilo) -  Seminario Java RMI di G.Cozzolongo

Java RMI: Remote Method Invocation

  Java Remote Method Invocation (RMI) è l’implementazione Java del modello ad oggetti distribuiti

  E’ un meccanismo che consente ad un oggetto su un JVM di invocare metodi di oggetti residenti in altre JVM

  La sintassi per le invocazioni remote è esattamente la stessa di quella delle invocazioni locali   Possono essere passati argomenti, calcolati nel contesto della

macchina chiamante   Possono essere restituiti valori, calcolati nel contesto della macchina

remota   Gli elementi chiave sono serializzazione e dynamic class loading

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Remote Method Invocation

Perche RMI? L’obiettivo è di permettere ad una applicazione in esecuzione su una macchina locale di invocare i metodi di un oggetto in esecuzione su un altro computer. Si definisce client il programma chiamante che ottiene riferimento all’oggetto remoto, server il programma che crea gli oggetti remoti. Tali applicazioni sono anche denominate distributed object application

•  miglioramento delle prestazione complessive

•  semplicità nella gestione delle risorse distribuite

•  incremento della potenza operativa

es: suddivisione di una computazione pesante in procedure più piccole, eseguite tutte su macchine diverse diminuendo in tal modo il tempo complessivo di esecuzione

Quali vantaggi?

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

2

Terminologia di base

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Semantica invocazioni remote

• La semantica delle invocazioni remote non è uguale pero a quella delle locali...

• Infatti, i tipi primitivi (int, float,...) sono sempre passati per valore (semantica Call By Value, CBV)

• Il chiamato lavora una copia del tipo • Gli oggetti remoti sono sempre passati per riferimento (Call By Reference, CBR)

• Il chiamato riceve un riferimento all’oggetto

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Semantica invocazioni remote

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

3

Interface Definition Language

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Un client è dotato dell'interfaccia dei metodi disponibili sul server remoto, ma tutta l'implementazione è lasciata sul lato server. Nel programma client i dettagli dell'implementazione dei metodi remoti sono quindi invisibili.

Ciò che realmente collega il client e il server in un sistema RMI è una connessione stratificata, trasparente agli sviluppatori, effettuata dal sottosistema RMI delle due macchine virtuali coinvolte.

Transport Layer (Connessione TCP/IP)

Remote Reference Layer

Stub

Remote Reference Layer

Skeleton

Client (Interfaccia)

Server (Implementazione)

Architettura dell’RMI

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Stub: proxy locale su cui vengono fatte le invocazioni destinate all’oggetto remoto

Skeleton: elemento remoto che riceve le invocazioni fatte sullo stub e le realizza effettuando le corrispondenti chiamate sul server (ormai solo per back compatibility)

Remote Reference Layer:- -fornisce il supporto alle chiamate inoltrate dallo stub definisce e supporta la semantica dell’invocazione e della comunicazione

Transport Layer: localizza il server RMI relativo all’oggetto remoto richiesto, gestisce le connessioni (TCP/IP, timeout) e le trasmissioni (sequenziali, serializzate), usando Java Remote Method Protocol (JRMP).

Registry: servizio di naming che consente al server di pubblicare un servizio e al client di recuperarne il proxy

Componenti base dell’RMI

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

4

The Stub and Skeleton

  A client invokes a remote method, the call is first forwarded to stub.

  The stub is responsible for sending the remote call over to the server-side skeleton

  The stub opening a socket to the remote server, marshaling the object parameters and forwarding the data stream to the skeleton.

  A skeleton contains a method that receives the remote calls, unmarshals the parameters, and invokes the actual remote object implementation.

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

The General RMI Architecture

  The server must first bind its name to the registry

  The client lookup the server name in the registry to establish remote references.

  The Stub serializing the parameters to skeleton, the skeleton invoking the remote method and serializing the result back to the stub.

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

The General RMI Architecture

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

5

Architettura di RMI

La struttura di un’applicazione RMI è organizzata in strati orizzontali sovrapposti

RMI Client

Stubs

Remote Reference Layer

Transport Layer

RMI Server

Skeleton

Remote Reference Layer

Transport Layer

Simulazione locale sul client

Oggetto reale eseguito sul server

Java Virtual Machine

Connessione fisica

Connessione virtuale

Il primo livello di questa connessione stratificata è rappresentato dagli stub (lato client) e gli skeleton (loto server) ai quali si riferiscono rispettivamente il client e il server senza occuparsi di ulteriori dettagli di più basso livello.

A loro volta, gli stub e gli skeleton demandano l'esecuzione di ciascuna attività allo strato immediatamente sottostante: il remote reference layer (RRL) che gestisce i riferimenti delle variabili agli oggetti remoti, usando la connessione TCP/IP del Transport layer sottostante.

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Architettura di RMI

  Lo strato più alto è costituito da applicazioni (client e server) eseguite dalla Java Virtual Machine.

  Lo stub e lo skeleton forniscono la rappresentazione dell’oggetto remoto: lo stub gestisce la simulazione locale sul client e, agendo come proxy, consente la comunicazione con l’oggetto remoto; lo skeleton invece consente l’esecuzione dell’oggetto remoto sul server.

  Il client esegue i metodi dell’oggetto remoto in modo del tutto analogo alla chiamata locale:

ris = OggettoRemoto.nomeMetodo(par1, par2,..) senza preoccuparsi dei dettagli della comunicazione.

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

La serializzazione

  Marshalling: processo di codifica di argomenti e risultati per la trasmissione.

  Unmarshalling: processo inverso di decodifica di argomenti e risultati ricevuti.

  In Java questo problema è risolto usando la serializzazione, che viene fatta in maniera trasparente dal supporto

  Serializzazione: trasformazione di oggetti complessi in semplici sequenze di byte=> metodo writeObject() su uno stream di output

  Deserializzazione: decodifica di una sequenza di byte e costruzione di una copia dell’oggetto originale=> metodo readObject() da uno stream di inputIn

  Java sono utilizzati in molti casi:   per memoria anche esterna   trasmissione tra macchine diverse(parametri e valori di ritorno in RMI)

  Esempio di storage http://lia.deis.unibo.it/Courses/cofimp/ Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

6

Il meccanismo alla base utilizzato da RMI per la trasmissione dei dati fra client e server è quello della serializzazione che permette il flusso di dati complessi all’interno di stream (può venir usata indipendentemente da applicazioni RMI)

•  La serializzazione consiste nella trasformazione automatica di oggetti e strutture in sequenze di byte manipolabili coi vari stream del package java.io

• Gli stream sono associabili sia a socket che a file

es:

Record record = new Record()

ObjectOutputStream oos = new ObjectOutputStream(myos)

oos.writeObject(record);

La serializzazione

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

•  Un oggetto è serializzabile se implementa l’interfaccia Serializable •  Si possono serializzare oggetti con struttura e complessità arbitraria, senza particolari differenze, a patto che l’oggetto sia serializzabile (implementi cioè l’interfaccia Serializable) es: public class Record implements Serializable{ private String Nome; public Record(String Nome){this.Nome = Nome} }

•  La serializzazione è ricorsiva ( un oggetto serializzabile deve contenere oggetti serializzabili) •  La maggior parte delle classi del JDK è serializzabile (eccetto alcune che adottano strutture dati binarie dipendenti dalla piattaforma)

La serializzazione

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Passaggio parametri

  Shallow Copy vs. Deep Copy   considerando un grafo di oggetti

  Passaggio per valore => Serializable Objects   Passaggio per riferimento => Remote Objects

Oggetti serializzabili: Oggetti la cui locazione non è rilevante per lo stato. Sono passati per valore: ne viene serializzata l’istanza che sarà deserializzata a destinazione per crearne una copia locale.

Oggetti remoti: Oggetti la cui funzione è strettamente legata alla località in cui eseguono (server) Sono passati per riferimento: ne viene serializzato lo stub, creato automaticamente dal proxy (stub o skeleton) su cui viene fatta la chiamata in cui compaiono come parametri Sistemi Distribuiti Multiagente

A.A.2010-11 Informatica Magistrale Università di Bari

7

Gli stub: quali azioni fanno?

stub cliente: <ricerca del servitore> <marshalling argomenti> <send richiesta> <receive risposta> <unmarshallin grisultato> restituisci risultato fine stub cliente;

stub servitore: <attesa della richiesta> <unmarshalling argomenti> invoca operazione locale ottieni risultato <marshalling del risultato> restituisci risultato fine stub servitore;

In aggiunta, il controllo della operazione ed eventuali azioni di ritrasmissione (entro un tempo di durata massima)

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Stub e Skeleton

  Stub e Skeleton sono oggetti generati dal compilatore RMI che gestiscono marshalling/unmarshalling e comunicazione (socket) tra client e server

Procedura di comunicazione: 1.  Il client ottiene un’istanza dello stub 2.  Il client chiama metodi sullo stub 3.  Lo stub

a.  crea una connessione con lo skeleton (o ne usa una già esistente) b.  marshalling delle informazioni associate alla chiamata (id del metodo e argomenti) c.  invia le informazioni allo skeleton

4.  Lo skeleton a.  unmarshalling dei dati ricevuti b.  effettua la chiamata sull’oggetto chei mplementa il server c.  marshalling del valore di ritorno e invio allo stub

5.  lo stub: - unmarshalling del valore di ritorno erestituzione del risultato al client Sistemi Distribuiti Multiagente

A.A.2010-11 Informatica Magistrale Università di Bari

Passaggio di parametri

Qualsiasi classe, i cui oggetti devono essere trasmessi con una connessione RMI, deve essere dichiarata come tale indicando che deve implementare l'interfaccia java.io.Serializable.

Ogni parametro passato o ritornato da un metodo remoto deve essere o un oggetto di una classe primitiva Java, o un tipo di dato primitivo oppure un oggetto che implementa l'interfaccia java.io.Serializable.

Un client richiede al server un riferimento ad un oggetto usando lo stub sul lato client. Il server ottiene la richiesta dallo skeleton sul lato server.

Tra i due c'è il remote reference layer che negozia le richieste convertendo gli oggetti in un formato trasmissibile attraverso la rete. Questa conversione è chiamata marshalling. Se i dati da trasmettere non sono né primitivi né serializzabili, lo stub lancerà un'eccezione MarshalException.

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

8

Il passaggio dei parametri

  Percorso dei parametri   Serializzati dalla Virtual Machine   Inviati sotto forma di stream al server   Deserializzati del server che li utilizza all’interno del

corpo del metodo invocato   Il risultato segue il percorso inverso fino ad arrivare al

client

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Gli strati RRL e TL

  Il Remote Reference Layer (RRL) ha il compito di instaurare un connessione virtuale fra il client e il server ( esegue operazioni di codifica e decodifica dei dati). RRL adotta un protocollo generico e indipendente dal tipo di stub o skeleton utilizzato.

  Il Transport Layer esegue la connessione vera e propria tra le macchine utilizzando le specifiche standard di networking di Java, e quindi le socket con il protocollo TCP/IP.

Si occupano della gestione “a basso livello” ( all’interno dell’architettura RMI) della comunicazione

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Il Transport Layer

  Il TL è responsabile del controllo dello stato delle vari connessioni

  I dati vengono visti come sequenze di byte da inviare o da leggere

  IL TL si incarica di localizzare il server RMI relativo all’oggetto remoto richiesto

  Esegue la connessione per mezzo di un socket

  Le classi e i metodi sono contenuti nei package java.rmi e java.rmi.server

  Si definisce oggetto remoto un oggetto che implementi l’interfaccia Remote i cui metodi possono essere eseguiti da un‘applicazione client posta su un’altra macchina virtuale

Programmare con RMI

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

9

Come trasformare un oggetto in un oggetto remoto?

public class MyServer{ public String concat (String a, String b){ return a+b; } } public interface MyServerInterface extend Remote{ public String concat (String a, String b)throws RemoteException; } public class MyServerImpl implements MyServerInterface extends UnicastRemoteObject{ public MyServerImpl() throws RemoteException{} public String concat (String a, String b)throws RemoteException{ return a+b;} } Sistemi Distribuiti Multiagente

A.A.2010-11 Informatica Magistrale Università di Bari

Sistemi distribuiti A.A.2006-07 Informatica specialistica – Università di Bari

Hello World con RMI: definire l’applicazione

Di cosa ho bisogno? 1. Scrivere l’intefaccia dell’oggetto remoto :

MessageWriter.java 2. Scrivere il server che implementa l’interfaccia e la

rende accessibile : MessageWriterImpl.java da cui in seguito generare stub e skeleton

3. Scrivere il codice per la pubblicazione del server HelloServer.java

4. Scrivere il client che richiede l’accesso all’oggetto remoto : HelloClient.java

una volta definite le classi posso passare alla compilazione e posso lanciare la mia applicazione RMI…

Sistemi distribuiti A.A.2006-07 Informatica specialistica – Università di Bari

Lanciare l’applicazione RMI

Una volta definite le classi (interfaccia, server, registrazione e client) posso compilare e lanciare il mio codice RMI.

Passi necessari: 5. Compilazione dei file .java 6. Generazione di stub e skeleton tramite il compilatore rmic 7. Avvio dell’RMI registry 8. Avvio dell’oggetto remoto (server) 9. Avvio del client

10

Sistemi distribuiti A.A.2006-07 Informatica specialistica – Università di Bari

Hello World (1) Scrivere l’intefaccia dell’oggetto remoto : MessageWriter.java

  L’interfaccia remota deve dichiarare tutti i metodi che si vuole poter richiamare in maniera remota   deve essere dichiarata public   deve estendere l’interfaccia java.rmi.Remote   ogni metodo deve dichiarare java.rmi.RemoteException

nella sezione throws per proteggere l’applicazione da anomalie derivanti dall’utilizzo di risorse remote

//l’interfaccia dell’oggetto remoto import java.rmi.*;

public interface MessageWriter extends Remote {

String writeMessage(String s) throws RemoteException; }

Sistemi distribuiti A.A.2006-07 Informatica specialistica – Università di Bari

Hello World: (2) Scrivere il server (oggetto remoto) MessageWriterImpl.java

  deve implementare almeno un’interfaccia remota   deve definire i costruttori dell’oggetto remoto

  deve fornire l’implementazione dei metodi invocati da remoto

  creare e installare il security manager   creare una o più istanza dell’oggetto

Implementare l’interfaccia remota

public class MessageWriterImpl extends UnicastRemoteObject implements MessageWriter { … }

• dichiara che implementa l’intefaccia MessageWriter ( con tutti i sui metodi)

• estende la classe UnicastRemoteObject per consentire la creazione di un oggetto remoto che

• adotta i protocolli di comunicazione di default di RMI basata sui socket e TCP

• rimane costantemente attivo Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

11

Definire i costruttori

  il metodo super() chiama il costruttore della classe UnicastRemoteObject che esegue le inizializzazioni necessarie per consentire di rimanere in attesa (listen) di richieste remote su una porta e poterle gestire (accept)

  potrebbe generare l’eccezione RemoteException se la connessione non fosse possibile

public MessageWriterImpl() throws RemoteException { super(); }

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Implementazione dei metodi remoti

  devono essere implementati tutti i metodi dell’interfaccia

  gli argomenti dei metodi e i risultati restituiti devono essere oggetti serializzabili

public String writeMessage(String s) throws RemoteException { return (s + " Ho ricevuto la tua stringa"); }

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Implementazione dell’oggetto remoto MessageWriterImpl.java

import java.rmi.*; import java.rmi.server.*; public class MessageWriterImpl extends UnicastRemoteObject implements

MessageWriter { public MessageWriterImpl() throws RemoteException { super(); } public String writeMessage(String s) throws RemoteException { return (s + " Ho ricevuto la tua stringa"); } }

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

12

Il security manager

  Il metodo main deve creare e installare un security manager, che può essere il RMISecurityManager o definito in altro modo

  Il S.M. garantisce che le classi che vengono caricate non eseguano operazioni per le quali non siano abilitate

  se il S.M non è specificato non è permesso nessun caricamento di classi da parte sia del client ( stub ) che del server

if(System.getSecurityManager() == null){ System.setSecurityManager(new RMISecurityManager()); }

Chi garantisce che il codice scaricato da remoto non esegua operazioni pericolose?

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

HelloWorld (3) Scrivere il codice per la pubblicazione del server HelloServer.java

  Nel metodo main si devono creare una o più istanze dell’oggetto che fornisce il servizio (oggetto remoto)

  Una volta creato, l’oggetto è pronto per accettare richieste remote

import java.rmi.*;

public class HelloServer { public static void main (String args[]) throws Exception {

MessageWriterImpl messageWriter = new MessageWriterImpl(); Naming.rebind("myservice",messageWriter); //pubblicazione interfaccia

}

}

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Registrare l’oggetto remoto

Naming.rebind("myservice",messageWriter);

Il client deve poter ottenere un riferimento all’oggetto remoto:

  RMI fornisce un registry degli oggetti per creare un’associazione (bind) fra un nome URL-formatted e un oggetto

  l’RMI registry è un name-service che consente ai client di ottenere riferimenti agli oggetti: una volta registrato l’oggetto i client possono farne richiesta attraverso il nome e invocarne i metodi

  nessun protocollo deve essere specificato nel primo argomento

  la porta di default su cui risponde il RMIregistry è la 1099, ma può essere cambiata

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

13

Registrare l’oggetto remoto (2)

  Un applicazione puo’ creare un’associazione solo sul RMIregistry del host locale

  I client possono invece eseguire la propria ricerca di oggetti su qualunque host

  L’operazione di registrazione può generare varie eccezioni   AlreadyBoundException, se il nome logico è gia

utilizzato   MalformedURLException, per errori nella sintassi

dell’URL   RemoteException negli altri casi

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

RMI Registry

Problema di Bootstrapping: un client in esecuzione su un macchina ha bisogno di localizzare un server a cui vuole connettersi, che è in esecuzione su un’altra macchina.

Tre possibili soluzioni: -  Il client conosce in anticipo dov’è il server -  L’utente dice all’applicazone client dov’è il server (es. e-mail client) -  Un servizio standard (naming service) in una locazione ben nota, che il client

conosce, funziona come punto di indirezione

Java RMI utilizza un naming service: -  RMI RegistryMantiene un insieme di coppie {name, reference} -  Name: stringa arbitraria non interpretata

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

HelloWorld (4) Scrivere il client che richiede l’accesso all’oggetto remoto : HelloClient.java

  Deve ottenere un riferimento all’oggetto remoto che vuole richiamare dal RMIregistry eseguito sul server, utilizzando un’istanza dello stub a cui passare hostname ( ed eventualmente porta) e nome dell’oggetto

MessageWriter myWriter = (MessageWriter) Naming.lookup("myservice");

  Richiama i metodi dell’oggetto secondo la sintassi solita String newstring = new String

(myWriter.writeMessage("Hello, world!")); System.out.println(newstring);

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

14

// il client per richiamare l’oggetto remoto Hello

import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.RMISecurityManager;

import java.rmi.*;

public class HelloClient { public static void main(String args[]) throws Exception { MessageWriter myWriter = (MessageWriter) Naming.lookup("myservice");

String newstring = new String (myWriter.writeMessage("Hello, world!")); System.out.println(newstring); } } Sistemi Distribuiti Multiagente

A.A.2010-11 Informatica Magistrale Università di Bari

(5) Compilazione

•  Compilare i file .java col javac per creare i file .class.

•  Generare stub e skeleton col comando rmic sul file che contiene l’implementazione dell’oggetto remoto (HelloImpl.class) rmic hello.MessageWriterImpl questo genera i file HelloImpl_Stub.class e HelloImpl_Skel.class NB: skeleton non è più in uso per le versioni della JVM successive alla 1.2

(6) Generazione di stub e skeleton

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

(7) Avvio dell’RMI registry

Lanciare in background RMIregistry col comando rmiregistry Questo processo utilizza per default la porta 1099

Lanciare il server - java HelloServer

Lanciare il client - Java HelloClient

(8) Avvio dell’oggetto remoto

(9) Avvio del client

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

15

Esempio: Calcolatrice con RMI

Implementazione dell’interfaccia

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface CalcolatriceServer extends Remote {

int addizione(int a, int b) throws RemoteException;

int sottrazione(int a, int b) throws RemoteException;

}

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Esempio: Calcolatrice con RMI Implementazione dell’oggetto remoto import java.rmi.*;

import java.rmi.server.*;

public class CalcolatriceServerImpl extends UnicastRemoteObject implements CalcolatriceServer { //implementazione del costruttore public CalcolatriceServerImpl() throws RemoteException{

super();

}

//implementazione dei metodi

public int addizione(int a, int b) throws RemoteException {

return a + b; }

public int sottrazione(int a, int b) throws RemoteException {

return a - b;

}

} Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Esempio: Calcolatrice con RMI Registrazione del server import java.rmi.Naming;

import java.rmi.*;

import java.rmi.server.*;

public class Registrazione {

public static void main(String args[]){

try {

CalcolatriceServerImpl obj = new CalcolatriceServerImpl();

Naming.rebind("calcolatrice", obj);

} catch (Exception e) {

e.printStackTrace();

}

}

} Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

16

Esempio: Calcolatrice con RMI

import java.rmi.Naming; import java.rmi.RemoteException; import java.util.InputMismatchException; import java.util.Scanner; public class CalcolatriceClient { public static void main(String[] arg){ try { CalcolatriceServer obj = (CalcolatriceServer) Naming.lookup("rmi://127.0.0.1/calcolatrice"); int risultato = 0; int scelta = 0; do {scelta = sceltaMenu(); switch (scelta) { case 1: System.out.println("addizione"); risultato = obj.addizione(1, 1); System.out.println ("1 + 1 = " + risultato); break; case 2: System.out.println("sottrazione"); risultato = obj.sottrazione(1,1); System.out.println ("1 - 1 = " + risultato); break; case 0: break; default: System.out.println("Errore, ripeti la scelta");break; } //end switch} while (scelta!= 0); } catch (Exception e) {e.printStackTrace();} }

public static int sceltaMenu(){ boolean valoreCorretto = true; int s = 0;

do{ Scanner input = new Scanner(System.in); System.out.println("Inserisci la tua scelta"); System.out.println("1 = addizione"); System.out.println("2 = sottrazione"); System.out.println("0 = exit"); try { s=input.nextInt(); valoreCorretto = false;} catch (InputMismatchException inputMismatchException) {input.nextLine(); // discard input so user can try again System.out.println("Scelta non valida. Inserisci un intero.\n");} } while (valoreCorretto); return s; }

}

Implementazione del Client

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Esempio:Implementare un Compute Engine

•  Un compute engine è un oggetto remoto che consente ad un server di ricevere dei task dai client, eseguirli e restituire il risultato.

•  Il task viene definito dal client ma viene eseguito sulla macchina del server.

•  Il task può variare indipendentemente dal server, l’importante è che rispetti una determinata interfaccia

•  Il compute engine scarica dal client il codice del task e lo esegue all’interno della propria Java virtual machine

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Interfacce utilizzate

Per implementare un compute engine servono due interfacce

• L’interfaccia Compute, che consenta ai client di inviare task all’engine

• L’interfaccia Task, che consenta all’engine di eseguire i task

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

17

Interfaccia Compute

package compute;

import java.rmi.Remote; import java.rmi.RemoteException;

public interface Compute extends Remote { Object executeTask(Task t) throws RemoteException; }

Questa intefaccia definisce i metodi che possono essere chiamati da altre virtual machine. Gli oggetti che implementano questa interfaccia diventano oggetti remoti.

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Interfaccia Task

package compute;

import java.io.Serializable;

public interface Task extends Serializable { Object execute(); }

Questa interfaccia è usata come argomento nel metodo executeTask dell’interfaccia Compute (definito precedentemente) e fornisce al Compute Engine il meccanismo per eseguire il task. Non è un interfaccia remota, quindi non è associata ad oggetti remoti.

Il metodo execute deve essere presente in ogni implementazione di questa interfaccia. Sistemi Distribuiti Multiagente

A.A.2010-11 Informatica Magistrale Università di Bari

//oggetto remoto per l’esecuzione dei task package engine;

import java.rmi.*; import java.rmi.server.*; import compute.*;

public class ComputeEngine extends UnicastRemoteObject implements Compute { public ComputeEngine() throws RemoteException { super(); } public Object executeTask(Task t) { return t.execute(); }

// metodo main }

Implementazione del Compute Engine

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

18

public static void main(String[] args) { if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); }

String name = "//host/Compute"; try { Compute engine = new ComputeEngine(); Naming.rebind(name, engine); System.out.println("ComputeEngine bound"); } catch (Exception e) { System.err.println("ComputeEngine exception: ” + e.getMessage()); } }

Metodo main del ComputeEngine

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

package client; import java.rmi.*; import java.math.*; import compute.*; public class ComputePi { public static void main(String args[]) { if (System.getSecurityManager() == null) { System.setSecurityManager(new RMIS...()); } try { String name = "//" + args[0] + "/Compute"; Compute comp = (Compute) Naming.lookup(name); Pi task = new Pi(Integer.parseInt(args[1])); BigDecimal pi = (BigDecimal) (comp.executeTask(task)); System.out.println(pi); } catch (Exception e) { System.err.println("ComputePi exception: " + e.getMessage()); }}}

Implementazione del client

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Implementazione dell’interfaccia Task package client;

import compute.*; import java.math.*;

public class Pi implements Task { /** costante usata nel calcolo di pi */ private static final BigDecimal ZERO = BigDecimal.valueOf(0); /** ...... ...... **/ public Pi(int digits) { this.digits = digits; } /*** Calcola pi.*/ //Poiché implementa l’interfaccia Task deve esserci questo public Object execute() { return computePi(digits); } public static BigDecimal computePi(int digits) { ...... } } Sistemi Distribuiti Multiagente

A.A.2010-11 Informatica Magistrale Università di Bari

19

Riassunto degli elementi necessari

  Due interfacce :   compute.java   task.java

  Il server che implementa l’interfaccia compute e comprende il metodo main per l’esecuzione: ComputeEngine.java

  L’implementazione del task da far eseguire: Pi.java   Il client che richiede l’esezuzione del task al server:

ComputePi.java

In più vengono generati i file per lo stub e lo skeleton:   ComputeEngine_stub.java   ComputeEngine_skel.java

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Esercizio

Provate a svolgere l’esercizio precedente (calcolatrice)

secondo modello illustrato per un generico Compute Engine

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

Altro esempio interessante dal web…

http://lia.deis.unibo.it/Courses/cofimp/

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari

20

Oltre a RMI per l’esecuzione remota

  RPC (Remote Procedure Call): rende possibile

gestire procedure facenti parte di applicazioni

remote rispetto al chiamante

  utilizzate soprattutto nei sistemi UNIX

  non si inseriscono nel contesto della

programmazione ad oggetti

  DCOM (estensione di COM di Microsoft )

  CORBA (Common Object Request Broker

Architecture)

Sistemi Distribuiti Multiagente A.A.2010-11 Informatica Magistrale Università di Bari