relazione - Ca` Foscari

Transcript

relazione - Ca` Foscari
ENTERPRISE JAVABEANS
Approfondimento per il corso Sistemi Distribuiti
A.A. 2002/2003
Marchiori Ilaria 780070
Università Ca’ Foscari – Venezia
CENNI SULLA PROGRAMMAZIONE A COMPONENTI
3
Introduzione
Che cos’e’ una componente?
Programmazione Java a componenti : JavaBeans
3
3
3
ENTERPRISE JAVABEANS
4
ARCHITETTURA EJB
EJB CONTAINER
ENTERPRISE BEANS (COMPONENTI SERVER DISTRIBUITI)
Tipologie di Enterprise Beans
Entity Bean
Session Bean
SERVER PER GLI EJB
CLIENT PER GLI EJB
5
5
7
8
8
11
13
13
CONCLUSIONI : UN CONFRONTO CON RMI E CORBA
14
CENNI SULLA PROGRAMMAZIONE A COMPONENTI
Introduzione
Quando parliamo della programmazione a componenti ci riferiamo alla programmazione orientata
agli oggetti che vede quest’ultimi come delle componenti. Verso questa tendenza si muovono le
tecnologie CORBA, DCOM, JAVA BEAN, in cui le componenti che si creano vengono poi
aggregate fino a fornire il prodotto che si vuole realizzare.
Ovviamente è indispensabile uno strumento di aggregazione che ci dia la sicurezza che le
componenti create si riescano a "legare bene" tra loro.
Che cos’e’ una componente?
Una componente è un’unità di distribuzione. Quando una componente viene distribuita in
commercio viene venduta per intero, non a pezzi. Se venisse prodotta da diversi fornitori (ovvero
ognuno realizza una parte della componente), i problemi di interoperabilità tra le singole parti
sarebbero frequentissimi.
Una componente è un’unità di composizione, visto che deve essere composta con altre che formano
il progetto.
Una componente non è un oggetto. Un oggetto è un unità di istanziazione: unità perchè dev’essere
un tutt’uno, un qualcosa di atomico, mentre di istanziazione perche’ è stato istanziato (un oggetto
ha un'unica identità che viene creata al momento dell’istanziazione). Una componente è un’unita’
di composizione e di sostituzione. Deve essere considerato come una scatola nera, un qualcosa
dentro il quale non si entra. Con essa possiamo interagire staticamente tramite un interfaccia.
Programmazione Java a componenti : JavaBeans
JavaBeans e' un modello di programmazione a componenti per il linguaggio Java. L’obiettivo e'
quello di ottenere componenti software riusabili ed indipendenti dalla piattaforma.
Inoltre tali componenti (beans) possono essere manipolati dai moderni tool di sviluppo visuali e
composti insieme per produrre applicazioni.
Ogni classe Java che aderisce a precise convenzioni sulla gestione di proprieta' ed eventi puo'
essere considerata un bean.
ENTERPRISE JAVABEANS
Basati sulla specifica EJB Sun Microsystems, gli Enterprise JavaBeans definiscono un’architettura
per lo sviluppo di componenti software che consentono di costruire applicazioni ad oggetti
distribuite, utilizzando Java.
Esse introducono un insieme di convenzioni, di classi e di interfacce (EJB API) che costituiscono
una piattaforma di sviluppo comune per i vari produttori di software, allo scopo di garantire due
aspetti fondamentali quali la portabilità e l’interoperabilità.
Quindi da un punto di vista architetturale EJB non è che un altro modo di vedere e di implementare
il modello della computazione distribuita, in cui gli oggetti distribuiti possono essere eseguiti in
remoto e su più macchine indipendenti fra loro.
Prima della comparsa di EJB, la soluzione più semplice per realizzare architetture distribuite full
Java era rappresentata dalla Remote Method Invocation (RMI); parallelamente troviamo anche
CORBA come complesso e potente sistema di gestione di oggetti remoti e distribuiti.
La novità introdotta rispetto a RMI e CORBA, dove i cosiddetti distribuited object services devono
essere implementati a mano o forniti per mezzo di software di terze parti, risiede nel fatto che nel
modello degli EJB tutto quello che riguarda la gestione dei servizi è disponibile e utilizzabile in
maniera del tutto automatica e trasparente agli occhi del client.
Quando si parla di servizi ci si riferisce a tutte quelle funzionalità volte alla implementazione dei
seguenti aspetti:
Transazioni: ovvero un insieme di operazioni che devono essere svolte in maniere atomica.
Come poi vedremo i container EJB offrono un sistema automatico per la gestione delle
transazioni.
Sicurezza: uno degli aspetti più importanti nell’ambito dei sistemi distribuiti; nel modello
EJB viene fornito il supporto offerto dal modello della security della piattaforma Java 2.
Scalabilità: la modalità con cui EJB opera permette la massima flessibilità e scalabilità in
funzione del traffico dati e del numero di clienti (ad esempio quali, quanti e come i beans
vengano forniti ai vari client è un meccanismo gestito automaticamente dal server).
EJB utilizza le funzionalità e la filosofia di base di RMI per realizzare strutture distribuite,
estendendone come visto i servizi in maniera trasparente.
ARCHITETTURA EJB
L’architettura EJB è basata essenzialmente su tre componenti: i server, i container ed i client.
Il server si occupa di fornire ai contenitori una serie di servizi di base per i vari componenti
installati.
Il contenitore offre una serie di funzionalità legate al life-cycle dei vari componenti, si occupa della
gestione delle transazioni, e del security-management.
Il client infine rappresenta l’utilizzatore finale del componente.
Vediamo più in dettaglio tale architettura, cominciando dall’analisi del container.
EJB CONTAINER
Il container è l’ambiente in cui operano gli Enterprise beans.
Offre una serie di funzionalità legate ad ogni aspetto della vita di un bean:
l’accesso remoto al bean
la sicurezza
le transazioni
la persistenza
la concorrenza
l’accesso alle risorse.
Il container isola il bean dall’accesso diretto da parte dei client.
Grazie all’intercettazione di tutte le richieste (da parte dei vari client) dirette al bean è in grado di
garantire la sicurezza e la persistenza.
Inoltre è in grado di gestire le transazioni che si instaurano fra chiamate successive, in relazione a
contenitori differenti e a server in esecuzione su macchine diverse.
Di conseguenza lo sviluppatore di un componente può quindi concentrarsi sui dettagli
implementativi della business logic, tralasciando gli altri aspetti legati alla gestione che sono a
carico del container.
L’unica cosa che deve fare chi sviluppa un componente è implementare una serie di interfacce
standard.
Il container inoltre può gestire le risorse in modo del tutto trasparente ed invisibile al client.
Ad esempio
può organizzare le risorse in pool
condividere un bean tra più client
togliere un bean non usato dalla memoria riservandosi la possibilità di reinstanziarlo al
momento del successivo utilizzo.
Dipendenza del bean dal container
Il bean dipende completamente dal container; si rivolge ad esso quando deve accedere ad una
connessione JDBC, accedere ad un altro enterprise bean, accedere all’identita' del cliente, ottenere
un riferimento a se stesso, accedere a proprieta' o risorse varie.
Sono tre i meccanismi che un bean ha a disposizione per interagire con il proprio container:
1. callback methods: questi metodi sono definiti nell’interfaccia EnterpriseBean, e vengono
chiamati automaticamente dal container in corrispondenza di particolari eventi della vita di
un bean. Ad esempio quando il bean sta per essere attivato o quando il suo stato sta per
essere salvato in un database o sta per essere rimosso dalla memoria. I callback methods
danno la possibilità al bean di compiere qualche operazione di manutenzione o di pulizia
immediatamente prima o dopo determinati eventi.
2. l’interfaccia EJBContext: è un riferimento direttamente al container, mediante il quale un
bean può chiedere informazioni riguardo all’ambiente in cui sta operando, come l’identità di
un cliente, lo stato di una transazione, un riferimento remoto a se stesso.
3. la Java Naming and Directory Interface (JNDI): consente di accedere a naming systems
quali LDAP, NetWare, ecc. Un bean può utilizzare JNDI per accedere a risorse quali
connessioni JDBC, altri enterprise bean, proprietà specifiche del bean.
Obbiettivi dell’interazione bean-container
L’interazione tra il bean e il container si basa pertanto su una serie di regole volte a garantire due
obbiettivi fondamentali:
portabilità del bean: un bean sviluppato per un container può essere trasportato su un altro
che offra migliori prestazioni, migliori caratteristiche o che costi meno.
semplicità di sviluppo del bean: come si e’ precedentemente detto, il container si occupate
degli aspetti di gestione più complicati, lasciando allo sviluppatore il compito di
concentrarsi solo sulle business rules. In questo modo se da un alto i beans sono sviluppati
più velocemente, dall’atro non sono richieste allo sviluppatore competenze specifiche di
programmazione distribuita (gestione delle transazione, della concorrenza, etc).
ENTERPRISE BEANS (componenti server distribuiti)
Gli Enterprise Java Beans sono componenti server distribuiti. Sono costituiti da due interfacce
pubbliche la cui implementazione viene effettuata automaticamente dal container al momento del
deploy del bean stesso.
Il client utilizza le interfacce pubbliche per creare, manipolare e rimuovere il bean dal server EJB.
Le due interfacce esportate dal bean verso i client rappresentano la visione che un client ha del bean
stesso, sebbene il client non agisca mai direttamente sulla componente, ma tutto passa sempre
attraverso l’ambiente.
Esse sono:
la home interface che fornisce i metodi per creare, distruggere o trovare un componente.
la remote interface che definisce i business methods (che possono rappresentare delle
azioni o task)
Un client utilizza la home interface per ottenere un riferimento alla remote interface di un bean.
La remote interface può contenere sia metodi per accedere o modificare i campi di un bean sia per
eseguire un qualche compito.
Implementando queste due interfacce ed i loro relativi metodi, il container è in grado di intercettare
le chiamate provenienti dal client, ed allo stesso tempo gli fornisce una visione semplificata del
componente stesso. Va notato che il client non ha la percezione di questa interazione da parte del
container. In questo modo si garantisce la flessibilità, la scalabilità oltre ad una non indifferenze
semplificazione del lavoro da svolgere.
TIPOLOGIE DI ENTERPRISE BEANS
Due sono i tipi di Enterprise Beans: gli entity bean e i session beans.
I primi rappresentano dati specifici o collezioni di dati. In genere forniscono metodi per
l’interazione con i dati che essi stessi rappresentano. Questo tipo di componenti sono persistenti,
dato che restano in vita per tutto il tempo che sono memorizzati all’interno del database.
I secondi invece rappresentano un collegamento con il client e soprattutto l’interazione con esso.
In genere i bean di questo tipo implementano una sequenza di operazioni all’interno di una
transazione.
L’implementazione di un bean e' una classe chiamata bean class. Essa incapsula i dati e
fornisce i metodi per accedervi.
ENTITY BEAN
Un entity bean rappresenta dati persistenti, ovvero memorizzati all’interno di un database.
L’accesso (e quindi l’utilizzo) da parte del client a tali dati avviene attraverso la remote interface del
bean.
Inoltre un entity bean implementa l’interfaccia javax.ejb.EntityBean.
Vengono sviluppati metodi per la ricerca del componente da parte del client: quello più importate è
il findByPrimaryKey(), il quale necessita al suo fianco della creazione di una chiave primaria
(classe PrimaryKey) per consentire l’identificazione unica del bean.
Per creare un Entity Bean, si può operare in due modi:
il client invoca i metodi di creazione della home interface
in alternativa si effettua una qualche operazione che aggiunga nel database dati che
rappresentino il bean.
Per avere un riferimento di un componente già esistente invece, diversi sono i modi con cui il client
può operare:
può ricevere il bean come parametro di una invocazione di metodi remoti
effettuare una ricerca presso il server per mezzo dei metodi di ricerca
ottenere dinamicamente un riferimento dal container il quale provvede a fornire il bean più
indicato.
A seconda di chi si occupa della persistenza, gli entità beans si distinguono in:
Container-Managed Persistence (CMP)
Bean-Managed Persistence (BMP)
CMP Entity Beans
Nel caso di entity beans di tipo CMP (Container-Managed Persistence) e' il container a occuparsi
della persistenza del bean.
Lo sviluppatore del bean non deve scrivere una riga di codice di accesso al database.
Il supporto alla persistenza è fornito dal server e varia da produttore a produttore, a seconda degli
strumenti più o meno sofisticati utilizzati per mappare i campi del bean all’interno del database.
Metodi di CMP
Per ogni create() nella home interface corrispondono una ejbCreate() ed una ejbPostCreate() con gli
stessi parametri. Esse vengono chiamate automaticamente dal container rispettivamente subito
prima e subito dopo che un nuovo bean e' stato creato ed un nuovo record e' stato inserito nel
database.
-
ejbCreate() viene utilizzata per inizializzare i campi del bean prima che questi vengano
scritti nel nuovo record.
Bisogna notare che un EJB tecnicamente non esiste finché il suo stato non è stato scritto nel
database.
-
ejbPostCreate() viene eseguita dopo la creazione, ma prima che il bean inizi a servire i
client.
I find methods, per un bean CMP, vengono gestiti automaticamente dal container: essi sono
utilizzati per localizzare determinati bean già esistenti, e si suddividono, a seconda del numero di
entità che possono restituire in risposta alla loro invocazione, in
-
single-entity find methods : restituiscono un solo entity bean oppure una
ObjectNotFoundException
multi-entity find method: restituiscono una collezione, eventualmente vuota, di entity bean.
Per un entità bean è obbligatorio definire un single-entity find methods chiamato
findByPrimaryKey() che prende in ingresso la chiave primaria del bean e serve per l’identificazione
univoca del bean stesso.
I callback methods vengono chiamati automaticamente dal container in corrispondenza di precisi
eventi nella vita del bean. Essi sono:
-
setEntityContext() viene invocata all’inizio della vita del bean e può essere utilizzata per
ottenere un riferimento al container, utile per accedere ad informazioni sulla sicurezza, sulle
transazioni o sul bean stesso.
unsetEntityContext() viene chiamata alla fine della vita del bean quando il riferimento al
container viene invalidato, e può essere utilizzata per le ultime operazioni di pulizia.
ejbLoad() viene chiamata subito dopo che lo stato del bean è stato caricato dal database.
ejbStore() viene chiamata subito prima che lo stato del bean venga salvato nel database.
Questi due metodi possono essere usati, per esempio, per decomprimere e comprimere i dati
letti e scritti nel database.
ejbActivate() e ejbPassivate() sono chiamate rispettivamente subito dopo che un bean è stato
attivato e subito prima che questo sia “passivato”, cioè venga disassociato dal suo
riferimento per essere rimosso dalla memoria o riutilizzato per un altro client.
BMP Entity Beans
Nel caso di entity beans di tipo BMP (Bean-Managed Persistence) il bean si occupa personalmente
della persistenza del proprio stato, seppur sempre assistito dal container, che si occupa delle
necessarie transazioni.
Vengono usati in genere quando si hanno esigenze particolari o quando si vuole avere un maggior
controllo sui dati memorizzati nel database.
Metodi di BMP
Un bean BMP differisce da un bean CMP principalmente per il significato assunto da ejbLoad(),
ejbStore().
-
ejbLoad() conterrà il codice per caricare lo stato del bean dal database, tipicamente
utilizzerà una istruzione select
ejbStore() conterrà una update
ejbCreate() conterrà una insert
ejbRemove() conterrà una delete
Per quanto riguarda l’implementazione delle ejbFind(), le single-entity devono ritornare una singola
chiave primaria, mentre le multi-entity devono ritornare collezioni di chiavi primarie. Il container
poi tradurrà queste chiavi in riferimenti ai bean veri e propri e li restituirà al client sotto forma di un
singolo riferimento o di una collezione di riferimenti.
SESSION BEAN
Un session bean rappresenta un insieme di procedure o task, che costituiscono dei servizi a favore
dei client.
Queste operazioni a favore dei client possono essere eseguite direttamente dal session bean oppure
utilizzando altri bean. Essi non rappresentano dati o entità di cui si voglia mantenere memorizzato
lo stato in un qualche database. Non godono, quindi, di persistenza.
Un session bean implementa l’interfaccia javax.ejb.SessionBean.
Essi di dividono in due categorie:
Stateless session bean: eseguono i loro compiti basandosi solo sulle informazioni passate
come parametri ai loro metodi: non mantengono delle informazioni tra una invocazione e
l’altra.
Stateful session bean: possiedono uno stato interno sebbene non persistente.
Come si diceva i session beans non sono stati progettati per essere persistenti, pertanto i dati che
essi memorizzano sono intesi relativamente ad una particolare sessione. E’ per questo motivo che
un session beans non può sopravvivere a crash di sistema o semplici restart del server; infatti il
riferimento creato all’interno del container per accedere a quel particolare bean, viene perso nel
momento in cui il client muore o la sessione finisce. Nel caso in cui il client necessiti di riutilizzare
un bean rimosso, deve utilizzare le informazioni in suo possesso (sul lato client) per poter ricreare il
componente sul server.
Stateless Session Beans
Questo tipo di session bean non mantiene un proprio stato interno, e di conseguenza ogni
invocazione di un suo metodo e' indipendente dalle precedenti. I metodi del bean si comportano
come tradizionali procedure.
Gli stateless session beans sono in genere più performanti degli stateful, e, poiché tutte le istanze
sono equivalenti tra loro, possono essere condivisi tra più client.
Metodi degli Stateless
La home interface di uno stateless session bean definisce solamente un metodo create() senza
argomenti, dato che non ha stato da inizializzare e non può avere metodi find() perché non è
persistente.
Principali metodi:
-
-
ejbCreate() può essere utilizzata per inizializzare variabili e acquisire risorse (ad esempio
una connessione)
ejbRemove() consente di disallocare le risorse occupate prima che il bean venga distrutto
Le chiamate a questi due metodi sono governate dalla politica di gestione delle risorse del
container: dopo una remove() da parte di un client, il container potrebbe decidere di non
distruggere il bean ma di metterlo a disposizione di altri client.
setSessionContext() consente di ottenere un SessionContext, che ha la stessa funzione
dell’EntityContext.
-
ejbActivate() e ejbPassivate() hanno una implementazione sempre vuota negli stateless
session beans.
Stateful Session Beans
Gli stateful session beans mantengono uno stato interno tra due invocazioni del client.
Ogni bean di questo tipo è associato ad uno ed un solo client: quindi essi non vengono condivisi tra
piu' client, anzi per tutta la sua esistenza un bean appartiene al client che l’ha creato.
Questo rende possibile, ad esempio, compiere una serie di operazioni a favore di un client
mantenendo in memoria le informazioni che non cambiano tra un’invocazione e l’altra, oppure un
risultato parziale.
Tipicamente la gestione dello stato viene effettuata automaticamente dalla coppia server-container e
in questo modo si riduce il lavoro che si deve svolgere in fase di sviluppo sia del client che del bean
stesso.
Quando uno stateful session bean non viene utilizzato per un certo tempo, il container puo' decidere
di rimuoverlo dalla memoria (passivation) e di salvare il suo stato in una memoria secondaria, da
dove puo' essere recuperato al momento della successiva riattivazione.
Metodi degli stateful
I callback methods ejbActivate() e ejbPassivate() vengono chiamati immediatamente dopo la
riattivazione di un bean ed immediatamente prima della sua disattivazione, rispettivamente.
ejbPassivate(), assieme a ejbRemove(), consente al bean di compiere un po’ di pulizia e di liberare
le risorse eventualmente occupate.
SERVER per gli EJB
Il server per i bean è l’elemento fondamentale di tutta la piattaforma EJB: questo componente infatti
svolge buona parte del lavoro necessario sia per rendere un componente utilizzabile dai vari client
remoti, sia per supportare i servizi più importanti (transazioni, mantenimento dello stato, sessioni,
sicurezza) associati ai vari beans.
Il processo di creazione di un bean e di deploy nel server passa per la definizione delle già citate
interfacce (Home interface e Remote interface) in modo che il server possa gestire il componente.
E’ la bean implementation class che implementa l’interfaccia remota e che fornisce di fatto il corpo
del bean, defininendone anche il comportamento.
La cosa estremamente interessante è che non è necessario fornire l’implementazione delle due
interfacce, compito svolto automaticamente dal server.
Per poter completare con successo la fase di deploy del bean nel server è necessario inoltre fornire i
cosiddetti deployment descriptors, operazione effettuabile al momento del deploy del componente
utilizzando il tool fornito dal server. Il deployment descriptor contiene le seguenti informazioni: il
tipo di bean, i nomi delle classi (home, remote, bean), come gestire le transazioni e la sicurezza sui
singoli metodi, il tipo di persistenza ed eventualmente quali campi salvare.
CLIENT per gli EJB
I client di un Enterprise JavaBean possono essere applicazioni, servlet, applet o altri EJB.
Sono tre le operazioni che un client deve effettuare:
1. utilizzare il nome del bean per localizzare la home interface
2. utilizzare la home interface del bean per ottenere un riferimento ad una sua istanza.
3. utilizzare direttamente il bean invocandone i metodi che mette a disposizione
I client quindi interagiscono con il bean unicamente attraverso i metodi definiti nella remote
interface.
La localizzazione avviene individuando da qualche parte la home interface, compito che viene
svolto per mezzo della classe java.naming.Context.
DISTRIBUZIONE DEGLI EJB
Gli Enterprise JavaBeans vengono distribuiti in un archivio JAR, contenente, tra l’altro, un
deployment descriptor in XML.
CONCLUSIONI : UN CONFRONTO CON RMI E CORBA
Come RMI e CORBA anche EJB si inserisce nello scenario della computazione distribuita.
RMI rappresenta il motore che permette tutto il funzionamento della tecnologia EJB. La scelta fra le
due soluzioni (solo RMI o EJB), deve essere fatta in funzione del tipo di applicazione che si deve
realizzare. Nel caso si vogliano realizzare sistemi semplici, dipendenti dal caso particolare, forse il
più semplice utilizzo di RMI può essere sufficiente; nel caso di situazioni complesse dove è
necessaria la massima flessibilità e scalabilità (come nell’ambito dell’e-commerce o JSP) allora la
soluzione di EJB può essere preferibile.
CORBA invece è più potente e più complesso sia di RMI che di EJB ed offre prestazioni migliori e
la possibilità di interagire con sistemi e tecnologie differenti. Ma non offre il supporto per i servizi
distribuiti, vero punto di forza di EJB.
In definitiva è utile utilizzare EJB in quei casi in cui si debbano realizzare applicazioni multistrato
distribuite, basate su oggetti mobili: e Java è la soluzione (l’unica) in grado di fornire massima
flessibilità e potenza implementativa.
BIBLIOGRAFIA
Per la relazione si è fatto riferimento al contenuto di articoli pubblicati nei seguenti siti:
http://www.mokabyte.com/
http://www.javaportal.it/