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/