|
Tutte le cose che ora si credono antichissime
furono nuove
|
|
| Home Page |
|
| Articoli |
|
| News |
|
| Forum |
|
| Classi |
|
|
|
|
|
Uno sguardo ad EJB 3.0
By
Giovanni Marigi e Stefano Mazzone
13 febbraio 2006
Valutazione Acquisita:
50
|
 |
|
Il 21 dicembre 2005 sono state rilasciate in “Proposed Final Draft” le specifiche 3.0 di Enterprise Java Bean. Secondo il Java Community Process, questo vuol dire, che dopo un periodo di approvazione e ballottaggio della “Public Review”, l’Expert Group ha inviato, attraverso lo Spec Lead (Specification Lead), il documento prodotto al PMO (Program Management Office) il quale lo ha pubblicato per il download sul JCP Web Site…. e noi lo abbiamo scaricato! :-) Dopo aver dato uno sguardo veloce, si prospettano grandi cambiamenti. Overview Questa versione promette una semplificazione delle API definite nelle versioni precedenti. Restano comunque ancora valide le specifiche EJB 2.1, poiché le nuove non le renderanno deprecate. Sarà quindi ancora possibile sviluppare Enterprise Java Bean utilizzando le specifiche EJB 2.1 e soprattutto utilizzare EJB scritti secondo specifiche 2.1 insieme ad EJB sviluppati seguendo le nuove 3.0. Obiettivi La promessa principale degli EJB 3.0 è di incrementare la produttività dello sviluppatore (anche detto Bean Developer) attraverso uno sviluppo semplificato degli stessi EJB. Con l’avvento delle Java annotation, anche gli EJB promettono una riduzione degli artefatti che un Bean Developer dovrà fornire. Ed è proprio attraverso le metadata annotation che l’utilizzo dei descrittori, anche detti EJB Deployment Descriptor, diventa superfluo. Allo stesso tempo l’utilizzo delle annotazioni favorisce la generazione, da parte del container, delle interfacce necessarie per un EJB a partire dalla Bean Class fornita. Le annotazioni possono essere usate per definire interfacce di business, riferimenti a risorse, (ORM) Object-Relationship Mapping e molto altro ancora. Le nuove specifiche permettono inoltre di definire, in maniera programmatica, proprietà di default per le annotazioni offerte. A tal proposito lo sviluppatore non dovrà più preoccuparsi di fornire proprietà e comportamenti cosidetti “comuni” per l’EJB container. Questo nuovo approccio viene chiamato “configuration by exception”. Anche l’incapsulamento di dipendenze e delle risorse JNDI viene reso indolore attraverso l’uso di annotazioni che permettono la quanto mai di moda “Code Injection”. I nuovi Enterprise Java Bean altro non sono che POJO (Plain Old Java Object). I POJO sono utilizzati per descrivere i nuovi EJB spogliati delle loro interfacce storiche. I POJO altro non sono che JavaBeans. Un Entity Bean è quindi una semplice classe Java con alcune annotazioni (quindi non persistente dalla nascita). Per fornire il supporto alla persistenza, sarà necessario associare questa classe Java (POJO) ad un EntityManager. Le vecchie interfacce vanno in pensione. Non sono infatti più necessarie per Session Bean ed Entity Bean. La Business Interface per un Session Bean è a sua volta una POJI (Plain Old Java Interface). Quindi niente più EJBObject, EJBLocalObject o Remote interface. Anche la Home interface sparisce. Inoltre, non è più necessario implementare interfacce di callback. Una grande promessa degli EJB 3.0 è il supporto all’ereditarietà ed il polimorfismo. Viene potenziato il linguaggio EJB QL introducendo il supporto ad inner ed outer join, bulk update e delete, subqueries e group by, oltre al supporto si statement nativi in linguaggio SQL. Anche la gestione delle eccezioni si semplifica, specialmente per ciò che riguarda le checked exception.
|
|
|
Metadata Annotation
|
top
|
|
Come già accennato, con l’introduzione delle metadata annotation nella J2SE 5.0 è possibile, in fase di programmazione, definire il comportamento ed il deployment della nostra applicazione. In particolar modo, negli EJB, le metadata annotation permettono di controllare il comportamento dell’EJB container, per richiedere ad esempio la fornitura di servizi “gratuiti” da parte di quest’ultimo o per effettuare, nel caso di Entity Bean, la mappatura ORM (Object-Relationship Mapping) verso un RDBMS (Relational DataBase Management System). Anche la generazione delle interfacce degli EJB viene controllata attraverso l’utilizzo delle metadata annotation. Le specifiche permettono, inoltre, la ridefinizione del comportamento attraverso le metadata annotation. E’ infatti possibile per chi sviluppa Enterprise Java Bean, utilizzare in maniera combinata le metadata annotation ed i classici DD (deployment descriptor). E’ importante ricordare, che i parametri specificati nel deployment descriptor hanno precedenza, sulle metadata annotation. Quindi nel caso in cui sia presente la definizione del parametro come metadata annotation e come elemento nel deployment descriptor, quest’ultimo avrà la precedenza. E’ garantita l’interoperabilità tra specifiche vecchie e nuove. In tal modo, un EJB scritto con le specifiche 3.0 può essere un client per un EJB scritto con le specifiche 2.1 e viceversa. Proprio questa interoperabilità favorisce la migrazione di applicazioni esistenti, con conseguente riutilizzo del codice.
|
|
Home Interface
|
top
|
|
Come già accennato la home interface, per Session ed Entity Bean, va in pensione. Questo vuol dire ad esempio, che dal punto di vista di un client, per creare un EJB di tipo Session si potrà procedere in due modi. Attraverso l’utilizzo di Application Client Container (ACC) oppure attraverso la lookup dell’interfaccia remota del Session EJB (SLSB o SFSB) e l’invocazione diretta dei suoi metodi di business. Per creare invece, da un client, un EJB di tipo Entity, sarà sufficiente invocare l’operatore new.
|
|
Enterprise Bean Class
|
top
|
La Bean Class rimane il posto dove implementare la nostra logica di business. Se il nostro EJB richiede una Business Interface è possibile implementare quest’ultima nella Bean Class oppure farla generare per noi a partire dalla Bean Class stessa, usando i metodi pubblici in essa presenti. In particolare, lo sviluppatore definisce la Bean Class ed utilizza le metadata annotation per generare gli altri artefatti, per modificare il comportamento del EJB container e per generare i deployment descriptor. Un requisito essenziale nella definizione della Bean Class è il tipo di EJB. Le annotazioni vengono utilizzate per definire EJB di tipo Stateless, Stateful, Entity e Message Driven. Inoltre, nel caso di un EJB di tipo Session, non è più necessario che la sua Bean Class implementi l’interfaccia javax.ejb.SessionBean. Per definire una Bean Class di nome CurrencyConverterBean, per un EJB di tipo Stateless, che implementi un Business Interface di nome CurrencyConverter, useremo le seguenti metadata annotations: @Stateless public class CurrencyConverterBean implements CurrencyConverter { public double euroToLira(double amount) {…} public double liraToEuro(double amount) {…} } La nostra Business Interface sarà quindi: public interface CurrencyConverter { public float euroToLira(float amount); public float liraToEuro(float amount); }
|
|
Business Interface
|
top
|
|
Come già accennato, nelle specifiche 3.0, la Business Interface di un EJB è una POJI (Plain Old Java Interface). Non è più richiesto che la Business Interface sia una interfaccia EJBObject o EJBLocalObject. EJB di tipo Session e Message-Driven richiedono una Business Interface. Per un Message-Driven Bean la Business Interface dipende dal tipo di messaggi usati, ad esempio nel caso di messaggi JMS, l’interfaccia usata sarà javax.jms.MessageListener. La Business Interface per una Bean Class può essere generata, oppure essere implementata all’interno della Bean Class stessa. In linea generale valgono le seguenti regole: • Un EJB la cui Bean Class non implementi nessuna Business Interface, avrà quest’ultima generata automaticamente. L’interfaccia generata sarà implementata dalla Bean Class come Local Interface, a meno che non sia presente nella Bean Class l’annotazione @Remote. • Per default, tutti i metodi della Bean Class dichiarati come public, ad esclusione dei metodi forniti per la code injection dal container, saranno presenti nella Business Interface generata. Questo comportamento di default, può essere modificato utilizzando la metadata annotation @BusinessMethod. Sarà quindi possibile decidere quali metodi di business esporre nella Business Interface. • Se la Bean Class implementa una singola interfaccia, quest’ultima rappresenterà la sua Business Interface. Questa interfaccia sarà implementata, dalla Bean Class, come Local Interface a meno che l’interfaccia non presenti l’annotazione @Remote, sia una interfaccia java.rmi.Remote o sia dichiarata come Remote attraverso il deployment descriptor. • Una Bean Class può implementare una o più interfaccia. Nel caso una Bean Class implementi più di interfaccia, ogni Business Interface dovrà presentare una metadata annotation che la identifichi come Local o Remote. Ma ora basta parlare, andiamo a toccare con mano un semplice esempio di Stateless EJB (SLSB). Durante il nostro esempio, sfrutteremo le caratteristiche dell’EJB container offerte dall’application server JBoss, probabilmente il primo che fornisce pieno supporto per le specifiche EJB 3.0. Per lo sviluppo dei componenti EJB 3.0 useremo l’IDE della Sun NetBeans e nello specifico la versione che supporta la nuova release di J2EE, la JEE 5.0. Nel download dell’IDE dovremmo per questo motivo scaricare la versione di NetBeans con il supporto per JEE 5.0 Il pacchetto di installazione di JBoss jboss-4.0.3SP1-installer.jar ci permette in fase di setup di decidere quale configurazione adottare e quali componenti rendere disponibili. Per abilitare il supporto agli EJB 3.0 si può decidere di scegliere una configurazione EJB 3.0 o ALL. Una volta installato JBoss siamo pronti per sviluppare il nostro primo Session Bean sotto NetBeans. Come primo step definiamo il server su cui intendiamo sviluppare ed eseguire il deploy delle applicazioni enterprise, aggiungendo un nuovo Server nella perspective Runtime Una volta configurato JBoss 4.0.X come server, possiamo direttamente da NetBeans eseguire operazioni di Start, Stop Debug dello stesso. Nella console di output di NetBeans possiamo vedere il log di JBoss e verificarne l’effettivo startup. Una volta che il server è in stato “running” siamo pronti per la creazione di un nuovo progetto EJB 3.0 Ricordiamoci di usare come versione di J2EE, Java EE 5.0 (il default è la J2EE 1.4) Decidiamo la tipologia di SessionBean che vogliamo creare (Session o Stateful) e se dotarlo delle interfacce remote o local, o entrambi. Diamo un’occhiata alle classi che sono state create nella definizione del nostro EJB di tipo Stateless: • CurrencyConverterEJBBean: la Bean Class vero e propria, dove vengono implementati i metodi di business del componente remoto • CurrencyConverterEJBRemote: la remote interface del componente EJB • CurrencyConverterEJBLocal: la local interface del componente EJB Come accennato, è evidente come la Bean Class e le stesse interfacce non necessitino più di estendere nessuna classe specifica. Essendo POJO solo componenti riusabili e non dipendenti da alcuna libreria né tanto meno vincolati a lanciare eccezioni remote. La classe CurrencyConverterEJBBean viene di fatto “marcata” attraverso l’annotation @Stateless. L’EJB container, grazie all’annotation, è in grado di stabilire che il componente dovrà essere creato e reso disponibile come Session EJB di tipo Stateless. Possiamo concentrarci sulla definizione dei metodi di business previsti per il nostro componente remoto, realizzandoli come se fossero dei comunissimi metodi java SE. Creiamo un semplice interfaccia java POJI in cui definiamo la segnatura dei nostri metodi di business: public interface CurrencyConverter { public float euroToLira(float amount); public float liraToEuro(float amount); } Le due interfacce definite per gli EJB, la remote e la local estenderanno la stessa Business Interface, non definendo la segnatura per questi metodi (stiamo supponendo che sia la local interface che la remote espongano gli stessi metodi). @Local public interface CurrencyConverterEJBLocal extends CurrencyConverter { } @Remote public interface CurrencyConverterEJBRemote extends CurrencyConverter { } La Bean Class che implementa le interfacce CurrencyConverterEJBLocal e CurrencyConverterEJBRemote fornirà l’implementazione per i metodi di business: @Stateless() public class CurrencyConverterEJBBean implements CurrencyConverterEJBRemote,CurrencyConverterEJBLocal { public float euroToLira(float amount) { ..... } public float liraToEuro(flot amount) { ..... } } Una volta definito e completato il nostro EJB siamo pronti per il packaging e il deploy del componente sotto JBoss. Prima dobbiamo però cambiare l’estensione del pacchetto che verrà creato per il deploy da .jar a .ejb3. Per far questo in NetBeans nella cartella nbproject accedere al file di properties project.properties e cambiare la definizione nella chiave/valore jar.name Infine nella cartella conf\src occorre eliminare i file descrittori previsti per gli EJB. Come abbiamo accennato, con gli EJB 3.0 la configurazione e la definizione dei parametri avviene attraverso le annotations. Cancelliamo quindi i file ejb-jar.xml e jboss.xml. Finalmente siamo pronti per il deploy del componente in JBoss. Nella perspective Project, eseguiamo il Deploy Project. Nella console di output di NetBeans di JBoss verifichiamo l’effettivo deploy del componente CurrencyConverter.ejb3. Ed ecco il nostro componente inserito nell’albero JNDI di JBoss con un default jndiName it.ktech.ejb3.CurrencyConverterEJBRemote.
|
|
Il client
|
top
|
Per completezza vediamo ora un piccolo esempio di client, da utilizzare per accedere al nostro EJB CurrencyConverter. Abbiamo scelto di accedere al nostro SLSB attraverso la lookup della sua Remote Interface e non utilizzando un lightweight container (ACC). Per far funzionare il tutto, occorre però aggiungere al classpath del nostro client, le seguenti librerie (alcune ad implementazione delle specifiche JEE 5.0 di JBoss): CurrencyConverter.ejb3 JBOSS_ROOT\client\jnp-client.jar JBOSS_ROOT\client\jboss-remoting.jar JBOSS_ROOT\client\jboss-j2ee.jar JBOSS_ROOT\client\jboss-aop-jdk50-client.jar JBOSS_ROOT\lib\jboss-common.jar JBOSS_ROOT\lib\concurrent.jar JBOSS_ROOT\server\default\lib\jboss.jar JBOSS_ROOT\server\default\lib\jboss-transaction.jar JBOSS_ROOT\server\default\lib\javax.servlet.jar JBOSS_ROOT\server\default\deploy\ejb3.deployer\jboss-ejb3.jar JBOSS_ROOT\server\default\deploy\jboss-aop.deployer\jboss-aspect-library-jdk50.jar Come mostrato nello snippet seguente, una volta ottenuto un riferimento al nostro EJB, invocheremo sullo stesso i metodi di business. package it.ktech.ejb3.client; import javax.naming.InitialContext; import javax.naming.NamingException; import it.ktech.ejb3.*; public class CurrencyClient { public static void main(String[] args) throws NamingException { InitialContext ctx = new InitialContext(); . . . . Some code for context’s initialization here . . . . CurrencyConverter converter = (CurrencyConverter) ctx.lookup(CurrencyConverterEJBRemote.class.getName()); System.out.println("Amount 1 Euro -->Euro to Lira:"+converter.euroToLira(1)); System.out.println("Amount 1000 Lire -->Lira to Euro:"+converter.liraToEuro(1000)); } }
|
|
Conclusioni e codice
|
top
|
|
Questo articolo, non aveva certo la pretesa di coprire in maniera esaustiva tutto ciò che viene offerto dalle nuove specifiche degli EJB. Ci sarebbe moltissimo da dire a proposito di Interceptors, Entity Bean, O/R Mapping ed EJB QL. Forse tutto ciò sarà spunto di nuovi …. e magari futuri articoli… …keep in touch guys! Download il codice di questo articolo.
|
|
|

Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons
|
|
|