Progettazione e realizzazione di un’applicazione J2EE Corso TAPS 2001/02 Gianna Reggio Che cosa occorre (1) • conoscere “concettualemente”/dal punto di vista del design le varie parti – per lo strato server-business (non vediamo quello Web) * Enterprise Javebeans * i servizi gestiti dal container (sicurezza, transaction, persistenza) * le API più rilevanti (messaging, Javamail) – per lo strato client * Java * GUI (AWT/SWING) – per lo strato EIS * useremo solo un database con EJBC o gestito dal container si assumono già conosciuti Che cosa occorre (2) • conoscere i dettagli a livello di codice, formati, procedure per realizzare le varie parti – Enterprise Javebeans sono specializazioni della class … e sono impaccati in un file .jar… • conoscere i tools che possono aiutare a svolgere le attività collegagte Enterprise Javabeans • Reusable components – classe di tipo “bean” + classi ausiliari – un oggetto a “run-time” • Business tier = container pieno di enterprise beans • sono di tre tipi – Session bean * eseguono un task per un client * es…………. – Entity bean * rappresentano un business entity object esistente nella memoria stabile * es…………. – Message-Driven bean * è un listener per messaggi asincroni del genere “Java Message Service” * es…………. Session Bean • rappresenta un singolo cliente all’interno del server J2EE, o meglio una sessione interattiva del cliente • per accedere ad un’applicazione installata sul server il cliente invoca i session beans • i session bean fanno il lavoro • non sono condivisi tra diversi clienti • non sono persistenti (cioè, i loro dati non sono salvati su un database) • quando il cliente termina la sua sessione il bean sparisce • Due tipi – Stateful e stateless Stateful Session Bean • lo stato di un oggetto consiste nei valori delle sue instance variables • In un stateful session bean, le sue instance variables rappresentano lo stato di un’unica sessione client-bean • Lo stato viene conservato per la durata della sessione client-bean • Se il cliente rimuove il bean o termina, la sessione finisce, e lo stato scompare • E questo non è un problema, poichè quando termina la “conversazione” tra il cliente e il bean finisce, non c’è bisogno di conservare lo stato Stateless Session Bean • un stateless session bean non contiene uno stato di una conversazione con un particolare cliente • Quando un cliente invoca un metodo di un stateless bean, le instance variables del bean possono contenere uno stato, ma solo per la durata dell’invocazione; quando il metodo è finito lo stato non è conservato • Eccetto durante l’invocazione dei metodi tutte le istanze dei bean stateless sono equivalenti, permettendo al container EJB di assegnarle ai clienti • Poichè stateless session beans possono supportare differenti clienti, possono offrire una migliore scalabilità per applicazioni che richiedono un grande numero di clienti • Un’applicazione, in genere, richiede meno stateless session beans che stateful session beans per supportare lo stesso numero di clienti • Di tanto in tanto il container EJB deve scrivere un stateful session bean sulla memoria secondaria, mentre gli stateless session beans non sono mai scritti, quindi gli stateless beans possono garantire una migliore efficienza che gli stateful beans Quando usare i Session Beans (1) • In generale, si dovrebbe usare un session bean se – In ogni momento, solo un cliente ha accesso all’istanza del bean – Lo stato del bean non è persistente, ma esiste solo per un periodo di tempo limitato (forse alcune ore) • Gli stateful session beans se vale una delle seguenti condizioni – lo stato del bean rappresenta l’interazione tra il bean e uno specifico cliente – Il bean deve ritenere delle informazioni sul cliente tra le invocazioni dei vari metodi da parte del cliente – Il bean media tra il cliente e le altre componenti dell’applicazione, presentando una vista semplificata al – dietro le scene il bean gestisce il work flow di diversi enterprise beans Quando usare i Session Beans (2) • Per migliorare l’efficienza si può usare un stateless session bean, se ha uno di questi tratti – Lo stato del bean non contiene dati specifici del cliente – Durante l’invocazione di un metodo, il bean esegue un compito generico per tutti i clienti (es., per mandare la conferma di un ordine via e-mail) – Il bean recupera un insieme di dati read-only usati frequentemente dai clienti (es., per recuperare I dati relativi ai prodotti speciali del mese) Entity Bean (1) • Rappresenta un “oggetto del business” conservato in un meccanismo di memoria persistente [database relazionale] (es., consumatori, ordini, e prodotti) • tipicamente un entity bean corrisponde ad una tabella in un database relazionale, ed ogni istanza del bean corrisponde ad una riga nella tabella • le differenze principali con i session beans – – – – sono persistenti sono condivisi hanno chiavi primarie per identificarli possono essere legati ad altri beans da relazioni Entity Bean (2) • Persistenza – Due tipi * Gestita dal bean ˚ Il codice del bean contiene le chiamate al database * Gestita dal contenitore ˚ il container EJB genera automaticamente le chiamate al database • Condivisi – Possono essere condivisi fra vari clienti – Poichè diversi clienti possono volere cambiare gli stessi dati, è importante che siano dotati di un meccanismo di transazioni – In genere, il contenitore fornisce la gestione delle transazioni – La definizione dei limiti delle transazioni viene data nel deployment descriptor del bean Entity Bean (3) • Chiave primaria – Ogni entity bean ha un unico “identificatore” (es., un entity bean consumatore può essere identificato da un codice) – La chiave primaria permette al cliente di localizzare un particolare entity bean • Relazioni – Come in un database relazionale, gli entity bean possono essere collegati da relazioni * Orientate * Con molteplicità 1 o molti – se la persistenza è * Gestita dal bean ˚ Il codice del bean deve gestire le relazioni * Gestita dal contenitore ˚ Il container ci pensa lui Persistenza gestita dal container (1) • Il container EJB gestisce tutti gli accessi al database necessari; il codice del bean non contiene istruzioni SQL – quindi, il bean non è legato ad uno specifico database, pertanto se il bean è riinstallato su un altro server, non occorre modificare o ricompilare il codice dal bean, il bean è molti più portabile • per generare gli accessi al database il container necessita delle informazioni data dallo • schema astratto dell’entity bean – è parte del deployment descriptor del bean, e definisce i campi persistenti del bean e le sue relazioni con altri entity bean – astratto per distinguerlo dallo schema “concreto” del/dei database a cui il bean sarà collegato Persistenza gestita dal container (2) • schema astratto dell’entity bean (cont.) – si specifica il nome di uno schema astratto nel deployment descriptor – questo nome viene usato in query scritte in EJB QL (Enterprise JavaBeans Query Language) – occorre definire una query EJB QL per ogni finder method (eccetto findByPrimaryKey) – la query EJB QL determina la query che è eseguita dal container EJB quando il finder method è invocato • campi persistenti – sono immagazzinati nel sottostante database – collettivamente costituiscono lo stato del bean – a runtime, il container EJB automaticamente sincronizza questo stato con lo stato del database – durante il deployment, il container tipicamente mappa l’entity bean su una tabella di undatabase e mappa i campi persistenti sulle colonne di tale tabella Persistenza gestita dal container (3) • campo relazione – è come una chiave esterna in una tabella di un database, identifica il bean collegato dalla relazione – come i campi persistenti, è virtuale ed è definita nella classe del bean con gli access method • le relazioni gestite dal container – hanno molteplicità * One-to-one * One-to-many * Many-to-one * Many-to-many – sono * unidirezionali (un solo campo relazione, nel bean di partenza) * bidirezionali (due campi relazione, in entrambi i bean) Quando usare gli Entity Beans • In generale, si dovrebbe usare un entity bean se – il bean rappresenta una business entity, non una procedura (es., “carta di credito” sarebbe un entity bean, ma il “controlla carta di credito” sarebbe un session bean) – lo stato del bean deve essere persistente; se il bean termina o se il server J2EE è spento lo stato del bean esiste ancora (in un database) Message-Driven Bean (1) • un enterprise bean che permette alle applicazioni J2EE di processare messaggi asincroni – agisce come un JMS message listener, che è simila ad un event listener eccetto che ricveve messaggi, invece di eventi – i messaggi possono essere mandati da ogni componente J2EE (application client, un altro enterprise bean, or una component Web) o da una applicazione JMS o da un sistema che non usa la tecnologia J2EE • differenze con i session bean – i clienti non accedono ai message-driven bean attraverso interfaccie (dopo) • assomigliano a stateless session bean – le istanze non tengono ne dati, ne lo stato di una conversazione con il cliente – tutte le istanze di un message-driven bean sono equivalenti, permettendo al container di assegnare i messaggi ad una qualunque istanza [es., una stream di messaggi può essere processata in modo concorrente] – un singolo message-driven bean può processare messagi provenienti da diversi clienti Message-Driven Bean (2) • caratteristiche – Le instance variables delle istanze dei message-driven bean possono mantenere dei valori durante il trattamento dei messaggi – quando un messaggio arriva, il container chiama il metodo del bean onMessage per processarlo – onMessage può chiamare metodi helper, o può invocare un session o un entity bean per processare l’informazione o immagazzinarla in una database – un messaggio può essere consegnato ad un message-driven bean dentro il contesto di una transazione così che se il processamento del messaggio è rolled back, il messaggio sarà redelivered • quando usare un message-driven bean – session bean e entity bean permettono di ricevere e mandare messaggi JMS e di riceverli in modo sincrono, ma non asincronamente – per ricevere messaggi asincronamente usare un message-driven bean Accesso ai bean per mezzo di interfacce • un cliente può accedere un session o un entity bean solo attraverso i metodi definiti nelle sue interfacce – esse definiscono il punto di vista da parte del cliente del bean – tutti gli altri aspetti (implementazione dei metodi, i setting contenuti nel deployment descriptor, schema astratto, e accessi al database) sono nascosti • interfacce ben progettate semplificano lo sviluppo ed il mantenimento delle applicazioni J2EE – non solo proteggono i clienti dalle complessità dell’EJB tier, ma permettono anche di cambiare il bean al suo interno, senza influenzare i clienti (es., si può cambiare la persistenza di un entity bean senza che il client se ne accorga) – ma se si cambiano i metodi nelle interfacce, allora occorre modificare i clienti – pertanto è importante isolare i clienti il più possibile dai cambi nei bean VALIDO IN GENERALE Accesso remoto • un cliente remoto di un bean ha le seguenti caratteristiche – può girare su una macchina diverso o su una Java VM diversa da quella del bean – può essere una componente Web, un’application client J2EE, o un altro enterprise bean – al cliente remoto la locazione del bean non interessa • un bean che permette l’accesso remoto deve avere due interfacce – remote interface * business method specifici del bean – home interface * life cycle methods (create e remove) * finder method per gli entity bean (servono a ricercare tali bean) Accesso remoto (esempio) Accesso locale • un cliente locale di un bean ha le seguenti caratteristiche – deve girare sulla stessa Java VM del bean – può essere una componente Web o un altro enterprise bean – la locazione del bean non è trasparente al cliente locale – frequentemente è un entity bean che ha una relazione gestita dal contenitore con un entity bean • un bean che permette l’accesso locale deve avere due interfacce – local interface * business method specifici del bean – home interface * life cycle methods (create e remove) * finder method per gli entity bean (servono a ricercare tali bean) Relazioni gestite dal contenitore e interfacce locali • se un bean è il target di una relzione gestita dal contenitore deve avere una interfaccia locale (per ricevere chiamate da coloro con cui è in relazione) accesso locale versus remoto (1) • occorre considerare i seguenti fattori – relazioni gestite dal contenitore * se un entity bean è il target di una di queste relazioni deve permettere l’accesso locale – Tight o loose coupling di bean * se hanno strette relazioni con altri bean, in genere beneficiano di accesso locale (più efficiente) – tipo dei clienti * se un enterprise bean è usato da un J2EE application client, allora dovrà permettere l’accesso remoto, dato che in genere essi girano su macchine diverse dal server J2EE * se i clienti sono componenti Web o altri enterprise bean, allora il tipo degli accessi dipende da quanto si vuole distribuire le varie componenti – distribuzione delle componenti * le applicazioni J2EE sono scalabili poichè le componenti del server-tier possono essere distribuite su molte macchine (es. le componenti Web possono girare su una macchine differente da quella dei bean che accedono) * in uno scenario distribuito gli enterprise bean devono permettere l’accesso remoto accesso locale versus remoto (2) – se non si è certi di quale tipo di accesso usare, scegliere remoto, in modo da evitare di precludere future realizzazioni distribuite – sebbene non comune, è possibile definire un enterprise bean con acesso remoto e locale, basta definire sia l’interfaccia remota che quella locale • tipo di accesso e prestazioni – la scelta della distribuzione della propria applicazione può influenzare le prestazioni * accesso remoto più lento * distribuzione permette compiti in parallelo, più veloce VALIDO IN GENERALE Tipo di accesso e passaggio dei parametri (1) • il tipo di accesso influenza il passaggio dei parametri dei metodi (anche del valore di ritorno) – un argomento di una chiamata remota è passato per valore, è una copia di un oggetto – un argomento di una chiamata locale è passato per riferimento, come ogni normale chiamata di un metodo in Java – i parametri delle chiamate remote sono più isolati, il chiamante ed il chiamato operano su copie differenti dell’oggetto parametro * se il cliente cambia il valore di tale oggetto, la copia nel bean non cambia ˚ questa forma di isolamento aiuta a proteggere il bean se il cliente inavvertitamente modifica il dato * in una chiamata locale, sia il cliente che il bean possono modificare lo stesso oggetto ˚ non usare troppo questa tecnica, poichè non permette di rimpiazzare la chiamata locale con una remota nel futuro Tipo di accesso e passaggio dei parametri (2) • granularità dei dati passati – poichè le chiamate remote in genere sono più lente di quelle locali, i parametri dei metodi remoti dovrebbero essere più “grossi” contenenti più dati, cosicché sono necessarie meno chiamate Il contenuto di un Enterprise Bean • per produrre un bean occorre fornire i seguenti file – Deployment descriptor * un file XML che specifica informazioni sul bean, come il tipo di persistenza, e le eventuali transazioni * esistono tool che aiutano a prepararlo – Enterprise bean class * implementa i metodi contenuto nelle sue interfacce: remote + home, oppure, local + home (ricordare che i message-driven bean non hanno queste interfacce) – Helper classes * altre classi necessarie alla classe bean, come classi exception e utility questi file devono essere impacchettati in un file EJB JAR file, il modulo che immagazzina l’enterprise bean un file EJB JAR è portabile e può essere utilizzato per costruire molte diverse applicazioni Convenzioni per i nomi degli enterprise bean Item Esempio Sintassi Enterprise bean name (DD) <name>EJB AccountEJB EJB JAR display name (DD) <name>JAR AccountJAR Enterprise bean class <name>Bean AccountBean Home interface <name>Home AccountHome Remote interface <name> Account Local home interface Local<name>Home LocalAccountHome Local interface Local<name> LocalAccount Abstract schema (DD) <name> Account quelli marcati DD si trovano nel deployment descriptor Il ciclo di vita degli Enterprise Bean • un enterprise bean passa attraverso differenti stadi durante la sua vita • ogni tipo di enterprise bean (session, entity, o message-driven) ha un tipo di vita differente • conoscere tali cicli di vita, aiuta a capire come funzionano, quali metodi occorre definire nelle relative classi Ciclo di vita di un Stateful Session Bean invocati dal cliente per metterlo toglierlo dalla memoria quando poco usato definito per ogni bean invocati dal container può ricevere le chiamate dei business method dal cliente Ciclo di vita di un Stateless Session Bean definito per ogni bean invocati dal container Ciclo di vita di un Entity Bean invocati dal cliente invocati dal container istanze non associate ad alcun identità Ciclo di vita di un Message-Driven Bean invocati dal container Transactions Il problema • Una tipica applicazione enterprise accede e modifica informazioni immagazzinate in uno o più database • Dato che questa informazione è critica per le attività del business, deve essere accurata, aggiornata, e affidabile • L’integrità dei dati si perderebbe – se diversi programmi potessero modificare la stessa informazione simultaneamente – o se il sistema fallisse mentre processava una “business transaction” e lasciasse i dati coinvolti modificati in modo parziale • Il meccanismo software delle transazioni assicura l’integrità dei dati in entrambi gli scenari – Controllano l’accesso ai dati da parte di diversi programmi – In caso di fallimento del sistema, assicurano che dopo il recovery, i dati siano in uno stato consistente riepilogo Transazione: cosa è? • Un gruppo di statement/azioni/step considerati come un tutt’uno • devono essere eseguiti tutti o nessuno, altrimenti l’integrità dei dati è persa – es…… • Una transazione può finire in due modi – con un commit * le modifiche dei dati fatte dagli statement sono salvate – o con un rollback * in caso di fallimento, gli effetti degli statement sono annullati • In J2EE le transazioni possono * Essere gestite dal container * Essere gestite dai bean Container-Managed Transaction • Si può usare per ogni tipo di enterprise bean (session, entity, o message-driven) • Lo sviluppo è semplificato, poichè non occorre marcare le transazioni sul codice del bean • Il container EJB pone i limiti delle transazioni • tipicamente, il container inizia una transazione immediatamente prima che un metodo del bean inizi, e la finisce giusto prima della fine di tale metodo • ogni metodo può essere associato con una singola transazione, transazioni multiple o innestate non sono ammesse • non è necessario associare una transazione con ogni metodo • quando si usa un bean per costruire un’applicazione, si specifica quali metodi del bean sono associati con le transazioni, fissando gli attributi di transazione Transaction Attributes (1) • Controllano lo scope di una transazione • Perché è importante ? • L’esecuzione di B è dentro lo scope della transazione dove è avvenuta la chiamata?, o dentro una nuova transazione • L’attributo di transazione di B permette di ripondere a ciò Transaction Attributes (2) Required – se il cliente è dentro una transazione e invoca il metodo, il metodo viene eseguito dentro la transazione del cliente – se il cliente non è dentro una transazione, il container inizia una nuova transazione prima di iniziare il metodo Funziona per la maggior parte dei casi * Quindi si potrebe usare come defualt, almeno all’inizio dello sviluppo, tanto è possibile cambiarlo dopo RequiresNew – se il cliente è dentro una transazione e invoca il metodo, il container fa le seguenti cose 1. sospende la transazione del cliente 2. inizia una nuova transazione 3. esegue il metodo dentro essa 4. dopo il completamento del metodo, riprende la transazione del cliente – se il cliente non è dentro una transazione, il container inizia una nuova transazione prima di iniziare il metodo Si deve usare quando si vuole essere certi che il metodo viene sempre eseguito in una nuova transazione Transaction Attributes (3) Mandatory – se il cliente è dentro una transazione e invoca il metodo, il metodo viene eseguito dentro la transazione del cliente – se il cliente non è dentro una transazione, il container lancia l’eccezione TransactionRequiredException Si deve usare quando si vuole essere certi che il metodo viene sempre eseguito nella transazione del cliente NotSupported – se il cliente è dentro una transazione e invoca il metodo, il container fa le seguenti cose 1.sospende la transazione del cliente 2.esegue il metodo fuori da ogni transazione 3. dopo il completamento del metodo, riprende la transazione del cliente – se il cliente non è dentro una transazione, il container non inizia una nuova transazione Si deve usare quando non è neccessario che il metodo sia eseguito in una transazione (evitare le transazioni, migliora le prestazioni) Transaction Attributes (4) Supports – se il cliente è dentro una transazione e invoca il metodo, il metodo viene eseguito dentro la transazione del cliente – se il cliente non è dentro una transazione, il container non inizia una nuova transazione Dato che il comportamento del metodo dipende varia in dipendenza del chiamante, usarlo con cauzione Never – se il cliente non è dentro una transazione, il container lancia l’eccezione RemoteException – se il cliente non è dentro una transazione, il container non inizia una nuova transazione Transaction Attributes (5) • Fissare i Transaction Attributes – Dato che sono conservati nel deployment descriptor del bean, possono essere cambiati durante tutte le fasi dello sviluppo delle applicazioni J2EE – Tuttavia lo sviluppatore del bean deve specificare questi attributi quando lo crea – ed essi dovrebbero essere modificati solo dallo sviluppatore di applicazioni, quando assembla le componenti – mentre, non si dovrebbe fare conto sull’installatore per fissarli – è possibile fissare gli attributi per un bean o per un singolo metodo (se ci sono entrambi, l’attributo del metodo ha la precedenza) Transaction Attributes: sommario Bean Client M(…) Transaction Attribute di M Bean Client Required No-trans RequiresNew No-trans New-trans T1 Mandatory No-trans New-trans errore NotSupported No-trans Supports No-trans Never No-trans T1 T1 T1 T1 T1 New-trans T1 T1 No-trans No-trans No-trans T1 No-trans error Bean-Managed Transaction • Permessa solo per session e message-driven bean – Utilizzando i meccanismi del database con JDBC – Utilizzando l’API JTA, che implementa le transaction con il “JTS” (Java Transaction Service) Fine lezione