Introduzione agli EJB 3.0

12
 JJ — n. 3 — marzo-apri le 2 007 Introduzione agli EJB 3.0  parte 1 di Fabio Staro Con la nuova specica 3.0 la SUN ha eseguito una reingegnerizza- zione della tecnologia EJB arricchendo l’API di nuove caratteristiche e semplicando, in modo radicale, lo sviluppo dei bean enterprise. Fabio Staro Dottore in Fisica  ` e Re- sponsabile Tecnico per i progetti Java presso la Direzione Ricerca ed Innovazione di En- gineering Ingegneria Informatica S.p.A.

Transcript of Introduzione agli EJB 3.0

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 1/11

 

JJ — n. 3 — marzo-aprile 2007

Introduzione agli EJB 3.0 parte 1

di Fabio Staro

Con la nuova specifica 3.0 la SUN ha eseguito una reingegnerizza-zione della tecnologia EJB arricchendo l’API di nuove caratteristichee semplificando, in modo radicale, lo sviluppo dei bean enterprise.

Fabio Staro

Dottore in Fisica e Re-sponsabile Tecnico peri progetti Java pressola Direzione Ricercaed Innovazione di En-gineering IngegneriaInformatica S.p.A.

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 2/11

 

pubblicato su

WWW.INFOMEDIA.IT

stampa digitale da

Lulu Enterprises Inc.

stores.lulu.com / infomedia

Infomedia

Infomedia e l’impresa editoriale che da quasi venti an-

ni ha raccolto la voce dei programmatori, dei sistemi-

sti, dei professionisti, degli studenti, dei ricercatori e dei

professori d’informatica italiani.

Sono piu di 800 gli autori che hanno realizzato per le te-

state Computer Programming, Dev, Login, Visual Basic

Journal e Java Journal, molte migliaia di articoli tecnici,

presentazioni di prodotti, tecnologie, protocolli, strumen-ti di lavoro, tecniche di sviluppo e semplici trucchi e stra-

tagemmi. Oltre 6 milioni di copie distribuite, trentamila

pagine stampate, fanno di questa impresa la piu grande ed

influente realta dell’editoria specializzata nel campo della

programmazione e della sistemistica.

In tutti questi anni le riviste Infomedia hanno vissuto del-

la passione di quanti vedono nella programmazione non

solo la propria professione ma un’attivita vitale e un vero

divertimento.

Nel 2009, Infomedia e cambiata radicalmente adottando

un nuovo modello aziendale ed editoriale e si e organiz-

zata attorno ad una idea di Impresa Sociale di Comunita,

partecipata da programmatori e sistemisti, separando le

attivita di gestione dell’informazione gestite da un board

comunitario professionale e quelle di produzione gesti-

te da una impresa strumentale. Questo assetto e in linea

con le migliori esperienze internazionali e rende Infome-

dia ancora di piu parte della Comunita nazionale degli

sviluppatori di software.

Infomedia e media-partner di manifestazioni ed eventi in

ambito informatico, collabora con molti dei pi u impor-tanti editori informatici italiani come partner editoriale e

fornitore di servizi di localizzazione in italiano di testi in

lingua inglese.

L’impaginazione automatica di questa rivista e realizzata al

100% con strumenti Open Source usando OpenOffice,

Emacs, BHL, LaTeX, Gimp, Inkscape e i linguaggi Lisp,

Python e BASH

For copyright information about the contents of Java Journal, please see the section “Copyright” at the end 

of each article if exists, otherwise ask authors. Infomedia

contents is © 2007 Infomedia and released as Creative

Commons2.5 BY-NC-ND.TuringClub content is© 2007 

Turing Club released as Creative Commons 2.5 BY-ND.

 Le informazioni di copyright sul contenuto di Java Jour-

nal sono riportate nella sezione “Copyright” alla fine di

ciascun articolo o vanno richieste direttamente agli au-

tori. Il contenuto Infomedia e© 2007 Infomedia e rila-

sciato con Licenza Creative Commons 2.5 BY-NC-ND. Il

contenuto Turing Club e© 2007 Turing Club e rilasciato

con Licenza Creative Commons 2.5 BY-ND. Si applicano

tutte le norme di tutela dei marchi e dei segni distintivi.

` E in ogni caso ammessa la riproduzione parziale o tota-

le dei testi e delle immagini per scopo didattico purch´ e

vengano integralmente citati gli autori e la completa

identificazione della testata.

 Manoscritti e foto originali, anche se non pubblicati, non

si restituiscono.

Contenuto pubblicitario inferiore al 45%.

 La biografia dell’autore riportata nell’articolo e sul

sito www.infomedia.it e di norma quella disponibi-

le nella stampa dell’articolo o aggiornata a cu-

ra dell’autore stesso. Per aggiornarla scrivere a

[email protected] o farlo in autonomia all’indirizzo

http: // mags.programmers.net  / moduli / biografia

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 3/11

 

JAVA Journal

31n.3 - marzo/aprile 2007

 educational

Introduzione agliEJB 3.0

Con la nuova specifica 3.0 la SUN ha eseguito una reingegnerizzazione della tecnologia EJB ar-ricchendo l’API di nuove caratteristiche e semplificando, in modo radicale, lo sviluppo dei beanenterprise.

>> di Fabio Staro ([email protected])

Premessa

Nelle applicazioni di classe enterprise l’uso della

tecnologia degli Enterprise JavaBeans è argomento

controverso tra i software architect poichè i servizi

messi a disposizione da un container EJB non sem-

pre bilanciano la complessità di sviluppo e deploy.

Con l’avvento degli EJB versione 2.0 il progettista

J2EE aveva a disposizione una tecnologia complessa

ma matura per realizzare applicazioni di classe enter-

prise, ossia applicazioni con un forte carattere distri-

buito e transazionale. La specifica degli EJB 2.x pre-

senta tre tipi di Enterprise JavaBeans: i Session Bean, i

 Message-Driven Bean e gli Entity Bean. Senza entrare in

dettaglio possiamo sintetizzare il carattere specifico

dei tre tipi di Enterprise JavaBeans (cfr. Tabella 1):

• i componenti di tipo Session Bean realizzano tipica-

mente i processi per la logica di business;

• i componenti di tipo Message-Driven Bean risolvono i

processi di tipo asincrono;

• ed infine i componenti  Entity Bean consentono la

persistenza dei dati essendo di fatto una tecnologia

ORM (Object Relational Mapping).

 

Come si è detto in precedenza, le applicazioni che

beneficiano maggiormente della presenza degli

Enterprise JavaBeans presentano componenti tran-

sazionali e delocalizzabili. Infatti i componenti EJB

possono essere “facilmente” distribuiti su diversi ser-

 ver, consentendo di fatto una migliore suddivisione

del carico computazionale, e possono garantire, se ve

ne fosse la necessità, un contesto transazionale unico

interagendo con diversi resource manager , per esempio

Prima Parte

TABELLA1 tipi di EJB

Enterprise Bean Descrizione

Session Bean

Sono i componenti enterprise per lo sviluppo della logica di business.

Si suddividono in due tipi: gli Stateless Session Bean e gli Stateful 

Session Bean. I primi sono senza stato, ossia ogni metodo del beanrappresenta una funzione di business fine a se stessa mentre i secondi

consentono di conservare lo stato durante le varie invocazioni che

avvengono con il client.

Message-Driven

Bean

Sono componenti enterprise per l’elaborazione asincrona. Sono

generalmente in ascolto su una coda o un topic JMS.

Entity Bean

Sono una tecnologia per la persistenza dei dati. Si dividono in  BMP 

e CMP. Nei bean di entità di tipo BMP gli statement SQL sono scritti

dallo sviluppatore del bean mentre nei bean di entità di tipo CMP gli

statement SQL sono generati in automatico dal container EJB.

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 4/11

 

JAVA Journal

n.3 - marzo/aprile 200732

educational

database e/o code JMS. Mostriamo di seguito uno scenario

complesso e tuttavia realizzabile  semplicemente attraverso

l’uso di EJB. Si osservi la Figura 1: una applicazione client

invoca un bean enterprise X che esegue tre operazioni. Più

precisamente:

• invia un messaggio verso un sistema di messagistica, per

esempio una coda JMS;

• aggiorna i dati presenti in un primo database;

• e poi invoca un secondo bean enterprise Y (che potrebbe

anche risiedere su un diverso server).

 A sua volta il bean enterprise Y esegue una operazione diaggiornamento su un secondo database. Lo scenario de-

scritto è una complessa transazione distribuita su diversi re-

 source manager . Grazie ai servizi offerti dall’ application server , 

dove risiedono i componenti EJB, assicurare la semantica

transazionale appena descritta non richiede uno sforzo

particolare nello sviluppo, se non l’uso delle normali API

 JDBC e  JMS, poiché è il server EJB a garantire il contesto

transazionale attraverso l’uso del two-phase protocol [2] e del-

le API JTA [3] e JTS [4].

L’esempio presentato è un caso complesso e limite. In

effetti i componenti EJB in una architettura Java portano

una serie di benefici che di seguito elenchiamo riman-

dando alla copiosa letteratura sul tema per gli opportuniapprofondimenti:

• Supporto alle transazioni distributite;

• Delocalizzazione delle componenti di business;

• Supporto per la gestione della sicurezza role-based;

• Supporto al pooling e al caching delle istanze dei bean;

• Supporto allo sviluppo di web service.

Tuttavia a fronte dei benefici sopra elencati sviluppare un

EJB versione 2.x richiede una buona dose di “pazienza”

e una sicura competenza. Per esempio, per sviluppare un

EJB di tipo Session Bean è necessario creare:

due interfacce;• una classe concreta;

• e un file XML che descrive la configurazione del compo-

nente.

Inoltre la classe concreta che rappresenta il bean vero e pro-

prio deve implementare l’interfaccia javax.ejb.SessionBean e,

di conseguenza, deve implementare una serie di metodi di

callback, invocati dal container EJB durante il ciclo di vita

del componente, che nulla hanno a che fare con la logica

di business. Nel caso degli  Entity Bean, poi, la complessità

aumenta a tal punto che, sebbene rappresentano la tecno-

logia “ufficiale” per la persistenza dei dati, molto spesso

non sono usati nei progetti per la presenza di alternative

più semplici, flessibili e performanti (cfr. Hibernate [5]).Con la specifica degli EJB 3.0 la SUN ha eseguito una

FIGURA 1 una applicazione client invoca un bean enterprise X che esegue varie operazioni

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 5/11

 

JAVA Journal

n.3 - marzo/aprile 2007 33

 educational

radicale reingegnerizzazione della tecnologia arricchendo

notevolmente l’API ma soprattutto semplificando note-

 volemte lo sviluppo dei componenti. A testimonianza di

ciò riportiamo quanto segue, direttamente dal documento

della specifica:

 La release EJB 3.0 dell’architettura Enterprise JavaBeans fornisce

 allo sviluppatore di applicazioni enterprise una API nuova e sem-

 plificata. Questa API è mirata alla facilità di sviluppo e rappresen-

ta una semplificazione delle API definite dalle precedenti versioni

 della specifica EJB.

In questo primo articolo introdurremo alcune delle princi-

pali “feature” degli EJB 3.0 e fin dai primi esempi si evi-

denzierà lo sforzo, pienamente riuscito da parte degli au-

tori della specifica, di semplificare e razionalizzare il lavoro

degli sviluppatori Java. Questo articolo è una introduzione

alla specifica 3.0 sebbene si dà per acquisita almeno una

conoscenza di base della specifica 2.x e delle problematiche

inerenti alla tecnologia EJB in generale. L’esempio riporta-

to è stato verificato con l’application server JBoss versione

5.0 [6] e con il database MySQL versione 5.0.27 [7].

Gestione di una biblioteca

L’esempio da realizzare, volutamente semplice al fine di

soffermarci sugli aspetti tecnici e non funzionali, è un

componente per la gestione di una biblioteca. Il compo-

nente consente una operazione di ricerca, restituendo

l’elenco dei libri di un autore, e una operazione di assegna-

mento di un libro presente in biblioteca ad un utente che

ne ha fatto richiesta. Pertanto la interfaccia di business del

componente è semplicemente:

public interface GestoreBiblioteca

{

public List<Libro> getLibri(String nomeAutore);

public void assegna(Persona persona, Libro libro)

throws LibroNonDisponibile;

}

Per implementare il componente gestore della biblioteca

come un EJB 3.0 di tipo session stateless è sufficiente:

• Creare una classe che implementi l’interfaccia di busi-

ness GestoreBiblioteca;

•  Annotare la classe con l’annotazione @javax.ejb.Stateless;

Lo stralcio di codice che segue riporta la definizione della

classe GestoreBibliotecaBean:

@Stateless (name=”Biblioteca”)

TABELLA 2 Alcune differenze tra la versione EJB 2.x e 3.x

EJB session 2.x EJB session 3.x

Business interface

Interfaccia che estende

 javax.ejb.EJBObject o

 javax.ejb.EJBLocalObject

Semplice interfaccia Java

eventualmente annotata.

Bean Class

Classe che deve implementare lainterfaccia javax.ejb.SessionBean e di

conseguenza implementare i metodi

di callback: ejbActivate(), ejbPassivate, 

ejbRemove(), setSessionContext().

POJO che implementa labusiness interface e dichiarato

con la annotazione @Stateless o

@Stateful.

Home interface

Obbligatoria. Deve estendere o la

interfaccia javax.ejb.EJBHome o la

interfaccia javax.ejb.EJBLocalHome.

Non presente.

Deployment

DescriptorObbligatori.

Non obbligatori. La via

preferenziale per caratterizzare un

EJB è attraverso le annotazioni

Dependency

Injection

Non presente. Presente.

Gli Entity Bean

versione 3 sono in

pratica un ORM

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 6/11

 

JAVA Journal

n.3 - marzo/aprile 200734

educational

public class GestoreBibliotecaBean implements

GestoreBiblioteca

{

}

Le poche righe di codice sopra riportate sono di fatto il no-

stro EJB 3.0 di nome Biblioteca e mostrano un carattere di-

stintivo ed innovativo degli EJB 3.0 rispetto alle precedenti

 versioni 2.x e 1.x: gli EJB 3.0 sono POJO, acronimo di Plain

Old Java Object, ossia semplici classi Java che non devonoimplementare interfacce particolari e/o metodi di callback 

e che non hanno un legame diretto con un container o con

un  application server . Con gli EJB 3.0 non sono più obbli-

gatori i file XML di configurazione, i talvolta complessi e

sicuramente prolissi deployment descriptor , essendo possibile

definire tutte le caratteristiche di un EJB attraverso le an-

notazioni. La Tabella 2 riporta alcune differenze e sempli-

ficazioni che si hanno per gli EJB di tipo session passando

dalla versione 2.x alla versione 3.x.

Il carattere remoto o locale di un EJB si definisce attraver-

so le due annotazioni

LISTATO 1 La classe GestoreBibliotecaBean

package it.articolo.ejb;

import it.articolo.ejb.interceptors.LogInterceptor;import it.articolo.ejb.interceptors.PerformanceInterceptor;

import java.util.List;import javax.annotation.Resource;import javax.ejb.Stateless;import javax.interceptor.Interceptors;import javax.sql.DataSource;import javax.ejb.TransactionManagement;import javax.ejb.TransactionAttribute;import javax.ejb.TransactionManagementType;import javax.ejb.TransactionAttributeType;import org.apache.commons.logging.LogFactory;import org.apache.commons.logging.Log;

@Stateless (name=”Biblioteca”)@TransactionManagement(TransactionManagementType.CONTAINER)public class GestoreBibliotecaBean implements GestoreBiblioteca { 

private static Log oLogger = LogFactory.getLog(GestoreBibliotecaBean.class);

  @Resource (name=”jdbc/exampleDatasource”)DataSource theDatasource = null;

@Interceptors({PerformanceInterceptor.class, LogInterceptor.class})public List<Libro> getLibri(String nomeAutore){

oLogger.info(“Invocato metodo EJB (CON INJECTION)”);List<Libro> oListaLibri = new DAOGestoreBiblioteca().getLibri(nomeAutore,

theDatasource);return oListaLibri;

}

@TransactionAttribute(TransactionAttributeType.REQUIRED)public void assegna(Persona persona, Libro libro) throws LibroNonDisponibile {

assegnaLibro(persona, libro);boolean result = diminuisciNumeroCopie(libro);

if (!result)throw new LibroNonDisponibile(“Il libro: “+libro.getTitolo()+” non è disponibile per il prestito”);

}

private boolean diminuisciNumeroCopie(Libro libro) throws LibroNonDisponibile {boolean operationResult = new DAOGestoreBiblioteca().diminuisciNumeroCopie(libro,theDatasource);

return operationResult;}

private void assegnaLibro(Persona persona, Libro libro) {new DAOGestoreBiblioteca().assegnaLibro(persona, libro, theDatasource);

}

}

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 7/11

 

JAVA Journal

n.3 - marzo/aprile 2007 35

 educational

contemporaneamente locale e remota ma che un EJB può

implementare più interfacce di business.

La dependency Injection

Il componente GestoreBiblioteca deve poter accedere al da-

tabase per poter espletare le sue funzioni di ricerca e di

assegnamento (cfr. Listato 1). Con la precedente versione

2.x degli EJB i passi necessari per accedere ad un database,

dopo aver definito un oggetto  datasource sull’application

server, sono:

• Definire una reference nel file ejb-jar.xml per il datasour-

ce;

• Connettersi al contesto JNDI;

• Eseguire una operazione di lookup della risorsa sull’albe-

ro JNDI, eseguendo poi il cast opportuno;

Le righe di codice che seguono sono esemplificative dei

passi sopra enunciati (il primo frammento di codice è re-

@javax.ejb.Remote

@javax.ejb.Local

Un componente EJB locale può essere invocato solo da

applicazioni client che risiedono nella medesima  Java

Virtual Machine mentre un componente EJB che espone

una interfaccia remota può essere invocato da applicazioni

client che risiedono in una diversa Java Virtual Machine ed

in generale su altri computer. Nel nostro esempio il com-

ponente gestore della biblioteca può essere invocato da

applicazioni client che non girano nella medesima JVM e

pertanto l’interfaccia di business del gestore è caratterizza-

ta dall’annotazione @Remote:

@Remote

public interface GestoreBiblioteca {

}

Osserviamo che una interfaccia di business non può essere

LISTATO 2 Metodo business assegna () della classe GestoreBibliotecaBean

…@TransactionManagement(TransactionManagementType.CONTAINER)public class GestoreBibliotecaBean implements GestoreBiblioteca{

… @TransactionAttribute(TransactionAttributeType.REQUIRED)public void assegna(Persona persona, Libro libro) throws LibroNonDisponibile {

assegnaLibro(persona, libro);boolean result = diminuisciNumeroCopie(libro);if (!result)

throw new LibroNonDisponibile(“Il libro: “+libro.getTitolo()+” non è disponibile per il prestito”);

}

private boolean diminuisciNumeroCopie(Libro libro) throws LibroNonDisponibile {boolean operationResult =

new DAOGestoreBiblioteca().diminuisciNumeroCopie(libro, theDatasource);return operationResult;

}

private void assegnaLibro(Persona persona, Libro libro) {

new DAOGestoreBiblioteca().assegnaLibro(persona, libro, theDatasource);}…}

LISTATO 3 Definizione del datasource verso MySQL in Jboss

<?xml version=”1.0” encoding=”UTF-8”?><datasources>

<local-tx-datasource><jndi-name>theDataSource</jndi-name><connection-url>jdbc:mysql:///test</connection-url><driver-class>com.mysql.jdbc.Driver</driver-class><user-name></user-name><password></password><exception-sorter-class-name/>

</local-tx-datasource></datasources>

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 8/11

 

JAVA Journal

n.3 - marzo/aprile 200736

educational

lativo al deployment descriptor, il file ejb-jar.xml, mentre il

secondo alla classe del bean).

<resource-ref>

<description></description>

<res-ref-name>jdbc/exampleDatasource </res-ref-name>

<res-type>javax.sql.DataSource</res-type>

<res-auth>Container</res-auth>

<res-sharing-scope>Shareable</res-sharing-scope>

</resource-ref>

// Codice per ottenere il contesto JNDI

Context initCtx = new InitialContext();

// Operazione di lookup

javax.sql.DataSource ds = (javax.sql.DataSource)

initCtx.lookup(“java:comp/env/jdbc/exampleDatasource”);

In generale i passi necessari per eseguire le operazioni di

lookup sull’albero JNDI per una risorsa esterna sono ripeti-tivi e soprattutto sono dettati dal contesto tecnologico e

non dalla logica di business. Inoltre, la dipendenza di un

componente EJB dall’API JNDI rende complesso il test

unitario del componente al di fuori di un container EJB.

Il problema è che nelle righe di codice sopra riportate la

classe del bean enterprise ha un legame diretto con la tec-

nica attraverso la quale si recupera un riferimento ad una

risorsa esterna (nell’esempio un datasource, ma di fatto può

anche essere una queue o un topic JMS, un altro EJB, ecc.).

La  dependency injection rovescia tale paradigma essendo il

container EJB a passare alla classe del bean enterprise una

reference alla risorsa esterna. Detto in altri termini, il con-

tainer EJB inietta nel bean enterprise una reference per la

risorsa esterna prima che sia eseguito un qualsiasi metododi business del bean. Lo stralcio di codice che segue mostra

come le operazioni di lookup sono di fatto eliminate nella

nuova specifica EJB 3.0:

public class GestoreBibliotecaBean implements

GestoreBiblioteca

{

@Resource (name=”jdbc/exampleDatasource”)

DataSource theDatasource = null;

}

 Attraverso l’annotazione @javax.annotation.Resource è va-

lorizzato da parte del container l’oggetto theDatasource di

tipo javax.sql.DataSource prima che sia invocato un qualsiasi

metodo di business dell’EJB da parte di un client.

In modo analogo, attraverso l’annotazione @javax.ejb.EJB 

è possibile referenziare un secondo componente EJB. Di

seguito un esempio di codice:

public class GestoreBibliotecaBean implements

GestoreBiblioteca{

@EJB SecondEJB secondEJB;

}

La sintassi equivale ad eseguire una operazione di lookup

dell’EJB individuato dalla reference  java:comp/env/ejb/ 

 secondEJB. Per apprezzare la semplificazione introdotta

riportiamo di seguito il codice presente in un EJB 2.x per

risolvere la medesima reference al secondo EJB:

Context ctx = new InitialContext();SecondEJBHome secondEJBHome = (SecondEJBHome)javax.rmi.Porta

LISTATO 4 Il file jboss.xml

<?xml version=”1.0” encoding=”UTF-8”?><!DOCTYPE jboss PUBLIC “-//JBoss//DTD JBOSS 3.2//EN” “http://www.jboss.org/j2ee/dtd/jboss_3_

2.dtd”><jboss><unauthenticated-principal>nobody</unauthenticated-principal><enterprise-beans><session><ejb-name>Biblioteca</ejb-name><resource-ref><res-ref-name>jdbc/exampleDatasource</res-ref-name><jndi-name>java:theDataSource</jndi-name></resource-ref><method-attributes/></session></enterprise-beans><resource-managers/>

</jboss>

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 9/11

 

JAVA Journal

n.3 - marzo/aprile 2007 37

 educational

bleRemoteObject.narrow(

ctx.lookup(“java:comp/env/ejb/secondEJB”),

SecondEJBHome.class);

SecondEJB secondEJB = secondEJBHome.create();

Gestione delle transazioni

Il gestore della biblioteca ha tra le sue funzionalità la

possibilità di assegnare un libro ad un utente che ne fa

richiesta. L’operazione di assegnamento si compone di

due passi fondamentali: il primo passo è il vero e pro-

prio assegnamento del libro all’utente della biblioteca

mentre il secondo passo è la verifica che vi sia almeno

una copia del libro in biblioteca per poterlo imprestare

(i passi sono stati così strutturati per mostrare la gestio-

ne automatica delle transazionin da parte del container

EJB). Nel caso in cui il libro risultasse non disponibile

la precedente operazione di assegnamento deve essere

annullata.

La specifica EJB 3.0 definisce due annotazioni per la ge-

stione delle transazioni:

• @TransactionManagement

• @TransactionAttribute

 Attraverso l’annotazione @TransactionManagement si di-

chiara se le transazioni sono gestite automaticamente dal

container EJB o manualmente dallo sviluppatore dell’EJB

attraverso l’API JTA; mentre con l’annotazione @Transac-

tionAttribute è possibile definire il comportamento transa-

zionale di un metodo di business dell’EJB. I valori validi

per l’annotazione @TransactionManagement sono definiti

nella enumerazione TransactionManagementType presente

nel package javax.ejb e sono:

• CONTAINER 

• BEAN

Mentre i valori validi per l’annotazione @TransactionAttri-

LISTATO 5 La classe client che invoca l’EJB

package it.articolo.client;

...

public class Client { 

public static void main(String[] args) throws NamingException{

Client oClient = new Client();Object oObject = oClient.lookupEJB(“Biblioteca/remote”);GestoreBiblioteca oEJB = (GestoreBiblioteca)oObject;List<Libro> libri = oEJB.getLibri(null);// VISUALIZZA A CONSOLE TUTTI I LIBRIoClient.log(libri.toString());

 Persona persona = new Persona();persona.setCognome(“Fabio”);persona.setNome(“Staro”);

 try {

// OPERAZIONE DI ASSEGNAMENTO DI UN LIBROoEJB.assegna(persona, libri.get(0));

} catch (LibroNonDisponibile e) {oClient.log(“ECCEZIONE:”+e.getMessage());

}}

 

private Object lookupEJB(String nomeEJB) throws NamingException{

Properties props = new Properties();props.put(Context.INITIAL_CONTEXT_FACTORY, “org.jnp.interfaces.NamingContextFactory”)

;props.put(Context.PROVIDER_URL, “jnp://localhost:1099”);Context ctx = new InitialContext(props);return ctx.lookup(nomeEJB);

private void log(String msg){

out.println(“[“+this.getClass().getName()+”]:”+msg);}

}

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 10/11

 

JAVA Journal

n.3 - marzo/aprile 200738

educational

bute sono definiti nella enumerazione TransactionAttribu-

teType, sempre presente nel package javax.ejb, e sono:

• NOT_SUPPORTED

• REQUIRED• REQUIRES_NEW 

• SUPPORTS

• MANDATORY

• SUPPORTS

La semantica dei valori sopra riportati è ben schematizzata

nella Tabella 3. A titolo di esempio osservando la Tabella

3 possiamo notare che se un componente client che non

ha iniziato una transazione invoca un metodo di un EJB

per il quale il valore dell’annotazione @TransactionAttribute

è REQUIRED il container EJB inizia una transazione nella

quale esegue il metodo di business. Viceversa, se sempre

il medesimo componente client inizia una transazione e

invoca il metodo precedente dell’EJB, allora il container

non inizia una nuova transazione ma esegue il metodo di

business nel contesto transazionale del client.

Se una o entrambe le annotazioni sono omesse, varranno i

 valori di default, che sono:

• CONTAINER per l’annotazione @TransactionManage-

ment

• REQUIRED per l’annotazione @TransactionAttribute

Per illustrare la gestione automatica delle transazioni da

parte del container riprendiamo l’esempio della biblioteca

e la classe GestoreBibliotecaBean. Questa presenta il metodo

di business assegna(). Il metodo fa due operazioni elemen-

tari: assegna il libro richiesto ad un utente della biblioteca

(operazione che si semplifica in un comando di  inserimen-

to sulla base dati) e diminuisce il numero di copie presenti

in biblioteca per il libro richiesto (operazione di aggiorna-

mento sulla base dati). Lo stralcio di codice nel Listato 2

mostra il metodo di business assegna ().

Il metodo  diminuisciNumeroCopie()  verifica per il libro ri-

chiesto il numero di copie presenti in biblioteca e nel caso

in cui il libro richiesto risulta presente, aggiorna il numero

di copie diminuendone il valore di una unità. Il metodo

nel caso di indisponibilità per il libro richiesto lancia la

eccezione applicativa  LibroNonDisponibile. In caso di ecce-

zione, la precedente operazione di assegnazione del libroall’utente richiedente, effettuata dal metodo  assegna (), 

deve essere sottoposta a rollback . L’eccezione LibroNonDi-

 sponibile è così definita:

@ApplicationException(rollback=true)

public class LibroNonDisponibile extends Exception

{

public LibroNonDisponibile(String message) {

super(message);

}

public LibroNonDisponibile(String message, Throwable

cause) {super(message, cause);

}

}

 Attraverso l’annotazione

@ApplicationException(rollback=true)

si informa il container EJB di eseguire una operazione di

rollback automatica al verificarsi della eccezione.

Metodi interceptor

Un’altra interessante caratteristica degli EJB 3.0 sono gli

interceptor . La definizione di un interceptor è fornita diretta-

mente dalla specifica:

“Un interceptor è un metodo che intercetta l’invocazione di un

metodo business o di un evento callback del ciclo di vita. Un meto-

 do interceptor può essere definito nella classe bean o in una classe

interceptor associata al bean.”

 Attraverso un metodo interceptor è possibile eseguire delle

funzionalità  prima e  dopo l’invocazione di un metodo di

business. Il metodo interceptor può essere dichiarato o nella

stessa classe del bean o in una classe separata che prende

il nome di interceptor class. Riprendiamo ora l’esempio della

biblioteca e supponiamo di voler misurare il tempo di ese-cuzione del metodo  getLibri() e di voler memorizzare, per

esempio su tabella, l’utente che ha invocato il metodo e

altre informazioni di contesto. Attraverso l’uso di due inter-

ceptor class è possibile separare l’operazione di misura della

performance e l’operazione di logging dalla operazione di

business vera e propria, migliorando in tal modo la chia-

rezza e la manutenibilità del codice. Di seguito è riportato

uno stralcio della classe GestoreBibliotecaBean.

@Stateless (name=”Biblioteca”)

public class GestoreBibliotecaBean implements

GestoreBiblioteca

{

@Interceptors({PerformanceInterceptor.class,LogInterceptor.class})

Il Server EJB

garantisce il contesto

transazionale

5/17/2018 Introduzione agli EJB 3.0 - slidepdf.com

http://slidepdf.com/reader/full/introduzione-agli-ejb-30 11/11

 

JAVA Journal

n.3 - marzo/aprile 2007 39

 educational

public List<Libro> getLibri(String nomeAutore)

{

}

}

E, a titolo di esempio, il codice della classe interceptor

PerformanceInterceptor:

public class PerformanceInterceptor {

private static Log oLogger = LogFactory.getLog(Performan

ceInterceptor.class);

@AroundInvoke

public Object performance(InvocationContext ctx) throws

Exception {

long start = System.currentTimeMillis();

try {

return ctx.proceed();

}

finally

{

long end = System.currentTimeMillis();

oLogger.info(“IL METODO:”+ctx.getMethod().getNa

me()+

“ E’ STATO ESEGUITO IN:

”+(end-start)+” MILLISECONDI”);

}

}

}

Osservando il codice si nota che attraverso l’annotazione@Interceptors è possibile dichiarare una o più interceptor class e con l’annotazione @AroundInvoke si definisce il metodoche agisce da interceptor. A questo metodo è fornito comeparametro di input un oggetto che implementa l’interfac-cia InvocationContext che è così definita:

public interface InvocationContext {

public Object getTarget();

public Method getMethod();

public Object[] getParameters();

public void setParameters(Object[] params);

public java.util.Map<String, Object> getContextData();public Object proceed() throws Exception;

}

L’interfaccia InvocationContext fornisce i metadati attraver-so i quali è possibile gestire la catena di invocazione degliinterceptor (nell’esempio riportato la catena di invocazioneè costituita dalle classi PerformanceInterceptor , LogInterceptor  e, ovviamente, GestoreBibliotecaBean). In particolare gli in-

terceptors in una catena di invocazione possono passarsi econdividere dati di contesto recuperandoli attraverso il me-todo getContextData() sulla istanza dello oggetto Invocation-

Context. Gli altri metodi dell’interfaccia InvocationContext

sono:

•  getTarget(): restituisce l’oggetto sul quale sarà invocato ilmetodo di business;

•  getMethod(): restituisce il metodo di business invocato;•  getParameters(): restituisce i parametri che saranno usati

come input nella esecuzione del metodo di business;•  setParameters(): consente di impostare nuovi parametri di

input per l’esecuzione del metodo di business;•  proceed (): esegue il metodo successivo nella catena di

invocazione.

L’invocazione di un interceptor method avviene nello stessocontesto transazionale e di sicurezza del metodo di busi-ness e un interceptor method può rilanciare runtime exception o  application exception definite nella firma del metodo dibusiness.

Deploy del componente

Il packaging del componente come EJB 3.0 è estremamen-te semplice. È sufficiente creare un file .jar che contiene laclasse bean, l’interfaccia di business e le eventuali classiinterceptor . Come si è detto all’inizio dell’articolo, i file de-

 ployment descriptor sono opzionali, ma se presenti devonoessere all’interno della cartella META-INF. Il deploy delcomponente nell’application server JBoss 5 è la semplicecopia del file .jar nella directory deploy del server.

Conclusioni

In questo primo articolo abbiamo introdotto alcune ca-ratteristiche degli EJB 3.0 evidenziando le semplificazioniintrodotte. Per quanto si è mostrato, è chiaro come gli EJB3.0 possano definirsi “ fine-grained object” non più complessidi un normale bean Java con la presenza di annotazioni,al contrario degli EJB versione 2.x visti come “corse-grained

heavyweight object”. Nei prossimi articoli approfondiremoulteriormente le nuove caratteristiche soffermandoci poisui message-driven bean e sui nuovi bean di entità.

Riferimenti

[1]: JSR 220: Enterprise JavaBeans,Version 3.0, http:

 //java.sun.com/products/ejb/docs.html.[2]: http://en.wikipedia.org/wiki/Two-phase_commit[3]: http://java.sun.com/products/jta/ [4]: http://java.sun.com/products/jts/ [5]: http://www.hibernate.org/ [6]: http://www.jboss.com/.[7]: http://www.mysql.com/ 

Note Biografiche

 Fabio Staro, dottore in Fisica è Responsabile Tecnico per i pro-getti Java presso la Direzione Ricerca ed Innovazione di Engi-

neering Ingegneria Informatica S.p.A.