MokaByte Numero  46  - Novembre 2000
 
JINI e JavaSpaces
prima parte
di 
Mauro Molino
Ci addentriamo in Jini e JavaSpaces due scenari inimmaginabili fino a poco tempo fà che dovrebbero  rivoluzionare il mondo della programmazione distibuita


In questa serie di articoli vedremo la teoria, ma soprattutto la pratica, della tecnologia JINI e in particolare dei Java Spaces, analizzandone caratteristiche e facendo una panoramica sulle enormi potenzialità offerte

Prefazione
Per chi fosse digiuno di JINI, l’argomento di cui trattiamo è la famigerata “distributed computing”. JINI è una tecnologia Java basata sul concetto di federazione di dispositivi. In pratica, una rete JINI è composta di una serie di entità in grado di fornire dei servizi ( computer,stampanti,scanner,programmi etc.), che al loro ingresso nella rete si registrano, comunicando la loro presenza a tutta la rete e rendendo altresì disponibili i drivers per il loro utilizzo. Nel momento in cui una macchina accede alla federazione , tramite un servizio di “lookup” ha la possibilità di sapere quali servizi sono resi disponibili e da chi. A questo punto ( privilegi permettendo) è in grado di accedervi e di utilizzarli. Grossomodo questa è la descrizione più semplice e banale di una struttura JINI.
JavaSpaces è una tecnologia JINI basata sulla creazione di spazi virtuali ( Spaces appunto), in grado di “ospitare” degli oggetti.Tramite questi spazi condivisi e accessibili in rete, diversi applicativi possono comunicare scambiandosi dati. Niente di particolare fin qui. Già, però se consideriamo che gli oggetti ospitati in un Java Space possono anche essere del codice, che la tecnologia mette a disposizione, spazi virtuali sia estemporanei che persistenti ( cioè in grado di conservare i dati anche in seguito ad un crash), che è già implementata la gestione delle transazioni, e che gli applicativi che vi accedono possono risiedere su macchine diverse, il tutto si fa molto più interessante. In pratica ci troviamo in mano uno strumento che permette di costruire applicativi distribuiti con una semplicità quasi sconvolgente (si, ho esagerato un pò !!!) senza dover rinunciare a caratteristiche di sicurezza ed affidabilità di tutto rispetto. 
Uno degli infiniti campi di applicazione degli spaces è l’elaborazione di dati distribuita, ad esempio il rendering di realtà virtuale. Possiamo immaginare un processo server che suddivide il lavoro in una serie di task e mette i task in uno space. I client, prenderanno ognuno un task dallo space e lo elaboreranno, restituendone poi il risultato. Quando tutti i task saranno stati completati, il server potrà prendere tutti i risultati parziali e comporre quello finale( nel nostro caso l’immagine). Non importa quanti e quali client siano connessi,  ognuno dei client è in grado di svolgere il task assegnatogli. Naturalmente più saranno i client connessi maggiore sarà la velocità di elaborazione complessiva.
Unica nota dolente: l’installazione. La preparazione dell’ambiente richiede l’installazione di tutta una serie di packages, che poi sono quelli di JINI. Ma niente paura, esiste una guida passo passo di estrema utilità per l’installazione e il test del tutto. La possiamo trovare al seguente URL: http://developer.java.sun.com/developer/technicalArticles/Programming/javaspaces/
 
 
 

Introduzione all’API
La vera potenza degli Spaces stà nella loro semplicità di utilizzo; fondamentalmente le operazioni possibili su un oggetto che stia in uno Space sono: read, take, write. Quindi possiamo leggere un oggetto( in pratica ne prendiamo una copia ma l’originale resta  nello Space), scriverlo(write) oppure prenderlo(take), che equivale a leggerlo sottraendolo allo Space. La magia è tutta quì.
A questo punto direi di passare direttamente ad un primo semplice esempio di utilizzo della API.
Prima di iniziare a scrivere codice, all’indirizzo http://java.sun.com/docs/books/jini/javaspaces/ scarichiamo il file JSBookExamples.zip che, oltre a contenere il codice degli esempi presenti nel testo indicato in bibliografia, contiene alcune classi utility delle quali ci serviremo.
Supponiamo di voler utilizzare uno space per la pubblicazione di annunci di vendita di oggetti. Intanto avremo bisogno di un oggetto che rappresenti l’inserzione vera e propria da scrivere nello space:

import net.jini.core.entry.Entry;

public class  Inserzione implements Entry {
 public String Categoria;
 public String Descrizione;
 public Integre Accessi; 

 public Inserzione(){
 }
}

La classe implementa l’interfaccia Entry, in quanto l’oggetto rappresenta appunto una Entry nello space. Le variabili accessibili dall’esterno devono essere dichiarate public.
Veniamo ora al processo responsabile di “mettere” l’inserzione nello space.
 

import net.jini.core.lease.Lease;
import net.jini.space.JavaSpace;
import jsbook.util.SpaceAccessor;

public class ScriviInserzione {
    public static void main(String[] args) {
        try {
            Inserzione inserzione = new Inserzione ();
            inserzione.Categoria = args[1];
            inserzione.Descrizione = args[2];

            JavaSpace space = SpaceAccessor.getSpace();
            space.write(inserzione, null, Lease.FOREVER);
            System.out.println(“Inserzione inserita nel Java Space);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Le classi importate, JavaSpace non ha bisogno di spiegazioni,  mentre Lease è la classe che si occupa di gestire il tempo di validità di un oggetto.
Quando viene effettuato il write dell’oggetto, il terzo parametro è un valore che fissa per quanto tempo l’oggetto sarà disponibile nello space. Alla scadenza del tempo fissato l’oggetto verrà rimosso.  In questo caso è stato fissato un tempo infinito, per cui l’oggetto potrà essere rimosso solo tramite un’operazione di “take”.  SpaceAccessor è una di quelle classi utility di cui accennavamo prima, che si occupa della ricerca di uno space attivo. Per il momento trascuriamo ciò che ci sta dietro, che vedremo invece in dettaglio nei prossimi articoli. Infatti non dimentichiamo che uno space può essere situato ovunque sulla rete, quindi i meccanismi necessari per accedervi non sono semplicissimi e  in questo primo articolo ciò che più ci preme è di dare un “quick start” per poter subito “assaggiare” la potenza dei Java Spaces. 
Andiamo avanti; il codice è piuttosto semplice: creiamo un oggetto Inserzione, gli assegnamo Categoria e Descrizione ( passati come parametri al lancio della classe) e scriviamo l’oggetto nello space.  Solo una nota: il secondo parametro del metodo write, che nel nostro caso è fissato a null; questo significa che stiamo rinunciando ad operare sull’oggetto sotto transazione. L’altra possibilità sarebbe stata di indicare al posto del null un oggetto Transaction, ma anche questo lo terremo in serbo per successivi approfondimenti.

Veniamo ora all’ultima fase del processo: la lettura dell’oggetto dallo space.

import net.jini.core.lease.Lease;
import net.jini.space.JavaSpace;
import jsbook.util.SpaceAccessor;

public class CercaInserzione {
    public static void main(String[] args) {
        try {
            JavaSpace space = SpaceAccessor.getSpace();
            Inserzione modello = new Inserzione ();
 Inserzione inserzione=(Inserzione)space.read(modello,null,Long.MAX_VALUE);
            System.out.println(inserzione.Descrizione);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Il client crea un’oggetto inserzione che serve da modello, cioè da filtro per la ricerca dell’inserzione all’interno dello space. Nel nostro caso il filtro non è molto selettivo, per cui restituirà qualsiasi inserzione ci sia dentro lo space. Per effettuare una selezione è sufficiente, prima di chiamare il “read”, assegnare i valori di filtro. Mi spiego: supponiamo di voler leggere le inserzioni della categoria “animali domestici”; prima di chiamare lo space.read scriveremo:

modello.Categoria=”animali domestici”;

in questo modo solo le inserzioni con la categoria voluta saranno considerate.
Per quanto riguarda i parametri del metodo read, il primo è l’oggetto modello, cioè quello che funge da filtro per la ricerca, il secondo è ancora legato all’utilizzo o meno delle transazioni e il terzo indica quanto tempo il metodo read debba rimanere in attesa nel caso in cui al momento della richiesta non sia presente nello space l’oggetto cercato. Nel nostro caso è stato specificato un tempo Long.MAX_VALUE che indica che il read attenderà all’infinito.
Cosa accadrebbe se nello spazio ci fosse più di una inserzione che “matchasse” il nostro modello?
Il read legge un oggetto alla volta che viene passato dallo space in maniera arbitraria. Ciò significa che per letture successive non sappiamo in che ordine ci verrebbero passate le inserzioni e non possiamo neanche essere sicuri che non ci venga passata più di una volta la stessa. La soluzione è creare delle nuove proprietà per il nostro oggetto inserzione in modo da poter rendere la ricerca il più selettiva possibile. Ad esempio si potrebbe aggiungere la data di inserimento, un indice progressivo etc., e in lettura specificherebbero più dati possibili per poter accedere effettivamente all’inserzione alla quale si è interessati. Nel caso in cui invece si volesse vedere ad esempio tutte le inserzioni di una certa categoria, si farebbe un ciclo di read specificando appunto la categoria e l’indice progressivo.
Il problema non si pone per la maggior parte delle applicazioni in quanto in generale si ha necessità di scrivere qualcosa di specifico nello space che poi verrà rimosso una volta utilizzato.
 
 
 

Conclusione 
Nel prossimo articolo oltre naturalmente a vedere nuovi esempi più complessi di utilizzo della API, cominceremo ad entrare nel dettaglio di funzionamento della tecnologia, parte che per ora è stata volutamente tralasciata, per capire meglio come funzioni il giocattolino. Nel frattempo chi vorrà cimentarsi nell’installazione  non si scoraggi se dovesse insorgere qualche problema, perchè alla fine sarà ripagato delle proprie fatiche............
 
 
 

Bibliografia
Java Spaces Principles,Patterns, and Practice-Freeman,Hupfer,Arnold-Addison Wesley

Chi volesse mettersi in contatto con la redazione può farlo scrivendo a mokainfo@mokabyte.it