Continuiamo a “recensire” la nuova specifica EJB 3.1, che prosegue la filosofia evolutiva introdotta con la 3.0, spingendo più avanti i meccanismi di automazione e astrazione. Questo mese parliamo delle caratteristiche di alleggerimento della nuova specifica: EJB Lite, web beans, embeddable containers.
EJB Lite
La caratteristica forse più importante della piattaforma JavaEE è la visione coerente e omogenea dei vari moduli e delle diverse tecnologie utilizzabili per la realizzazione di svariati tipi di applicazione e per la soluzione delle molteplici problematiche enterprise. Questa visione globale, però, è spesso additata come la principale limitazione della piattaforma: essa infatti obbliga ad abbracciare in toto la JavaEE Philosophy, impendendo una adozione graduale o modulare della specifica EJB. Tutto ciò può rappresentare un fattore limitante quando si tratti di adottare la JavaEE sia da parte dei programmatori alle prime armi, sia nei progetti a basso budget o con limitati skill tecnologici.
L’introduzione dei Profili in JavaEE 6 (vedi [PROFILES]) rappresenta senza dubbio una prima risposta alla sempre crescente necessità di semplificazione e alla richiesta di poter usare solo alcune parti della piattaforma.
Il concetto base è che spesso un layer client di uno strato EJB finisce per usare solamente alcune funzionalità, probabilmente sempre le stesse: la injection per ricavare i remote reference, la gestione della persistenza, componenti remoti stateless session beans e probabilmente le transazioni dichiarative.
La nuova specifica EJB 3.1 si sta quindi muovendo nella direzione di offrire un nuovo approccio modulare (uso/studio/imparo a usare “solo quello che mi serve”) con una versione “tagliata” delle API. Se, da un lato, credo che l’utilizzo modulare delle tecnologie semplifichi drasticamente il processo di apprendimento del programmatore, non sono ancora convinto che la riduzione delle API a disposizione possa poi dare dei benefici concreti (specialmente se si considera l’elenco degli assenti in EJB Lite come riportato nella tabella di figura 1).
Figura 1 – Tabella di confronto fra EJB Lite e EJB Full feautured.
È comunque vero che EJB Lite viene considerato la condizione necessaria per la realizzazione di container semplici e utilizzabili anche in contesti differenti (i cosiddetti “pluggable containers”, di cui parliamo più avanti nell’articolo): questi potrebbero veramente essere una piccola rivoluzione (basta vedere lo spezzone di codice che mostra come inizializzare un container embedded).
Ecco l’elenco delle tecnologie proposte nella nuova specifica:
- Stateless, Stateful e Singleton session beans
- Solamente interfacce locali o nessun uso di interfacce
- Nessun supporto per l’invocazione asincrona
- Interceptors
- Gestione dichiarativa della sicurezza
- Gestione dichiarativa e programmativa delle transazioni
WebBeans e EJB
I web beans sono una delle novità più interessanti introdotte con il prossimo venturo JavaEE 6. Il concetto base che ha guidato nello sviluppo di questa interessante novità è la possibilità di semplificare lo sviluppo di applicazioni enterprise multilivello in cui la parte web (spesso basata su JSF) abbia necessità di utilizzare la business logic residente in componenti session bean remoti. Questa operazione è già adesso possibile, per mezzo della una iniezione nel backing bean di un reference a un session bean, tramite l’annotazione @EJB, e porta di fatto a ridurre il backing bean a un semplice proxy (o collante) nei confronti del session bean.
La buona progettazione di una architettura enterprise ci dice che questo approccio è benefico quando vogliamo massimizzare il disaccoppiamento dei vari strati della applicazione: proprio per massimizzare la separazione logica dei vari livelli, spesso si finisce per aumentare tale disaccoppiamento, magari introducendo sui due lati del confine JSF-EJB oggetti basati sui noti pattern Session Facade (lato EJB) e Business Delegate (lato web, o comunque lato client). Come spesso viene insegnato nei manuali di progettazione, maggiore è il livello di disaccoppiamento e minori saranno gli impatti in fase di refactoring o sostituzione di uno o più componenti del sistema. Nonostante gli ormai riconosciuti influsssi benefici di questa organizzazione, ci sono casi in cui la realizzazione di una applicazione web non richiede la “potenza di fuoco” di un tipico scenario JavaEE: per necessità temporali, per requisiti di progetto (dobbiamo fare un prototipo) o più pragmaticamente per i limiti imposti dagli skill del team di progetto, ci sono una serie di casi in cui fare le cose in modo eccessivamente strutturato e metodico può non essere vantaggioso.
Web Beans (WB) è una nuova specifica che permette di ottenere questa semplificazione eliminando la necessità di scrivere grandi quantità di codice di collegamento e portando l’uso dei session bean direttamente a contatto con le pagine JSF. Ovviamente questo approccio è in netta contrapposizione con i manuali di architettura e di pattern programming in cui si dà sempre forte enfasi alla necessità di separare i layer architetturali con appositi schemi progettuali nell’ottica di disaccoppiare il più possibile massimizzando la coesione.
Dato che una trattazione approfondita della specifica WB esula dagli scopi di questo articolo (per maggiori dettagli rimandiamo a una puntata dedicata), cercheremo di vedere qui solo brevemente le implicazioni dell’adozione dei WB.
Usare componenti EJB come JSF Backing Beans
Si supponga di avere una applicazione EJB composta da alcuni session bean che contengono della business logic e che la parte di persistenza sia demandata ad altrettanti entity beans.
In uno scenario del genere, normalmente la parte di business logic nasconde lo strato di persistenza: il backing bean si interfaccia direttamente con il session bean in modo da utilizzarne la logica di business. I dati sono spesso passati da un layer attraverso appositi DTO o più comunemente tramite VO che sono la versione standalone dei POJO-Entity beans.
Nel nuovo scenario possiamo pensare di ridurre il rigore dello schema organizzativo ed esporre tutti i componenti al layer web:
@Component
@Stateless
@Named(“businessLogicBean”)
public class BusinessLogicBean {
@PersistenceContext
private EntityManager entityManager;
@In
private MyEntiy myEntity
public void saveTheEntity() {
entityManager.persist(myEntiy);
}
}
@Component @Entity @Named("myEntiy") public class MyEntiy { // alcune proprietà di persistenza protected propertyA; protected propertyB; protected propertyC; // seguono i metodi GET/SET sulle proprietà }
In questo caso l’annotazione @Component posta sia sul session che sull’entity permette di registrare i due oggetti nel WebBeans container. La annotazione @Named assegna il nome con cui tale container può identificare tali oggetti. La @In invece inietta la variabile direttamente nel session bean assegnandone il ruolo di parametro di input direttamente dal form HTML della web application:
... ...
Inserisci il valore dell’entità |
... action="#{businessLogicBean .saveTheEntity }"/> ... ...
In questo schema il session bean finisce per diventare un componente “back of the page”, invocabile semplicemente tramite rudimentali operazioni di scripting. Il risultato finale è certamente molto intrigante, la semplificazione che ne deriva è innegabile: il fatto di non usare pattern di separazione e coesione non dovrebbe infastidire i puristi della programmazione enterprise. Se ci si pensa, in uno scenario come questo perde di significato la presenza di un business delegate, il cui scopo, ricordiamo, è quello di nascondere la complessità legata al reperimento delle risorse remote: grazie all’uso delle annotazioni della IOC la complessità qui è eliminata a priori. Probabilmente avrebbe ancora senso utilizzare un Session Facade, ma nulla impedisce al progettista di usare nelle pagine JSF un session-backing bean che sia anche facade (con l’accorpamento delle funzionalità anche i nomi si allungano).
Standardized Global JNDI Names
Una delle novità minori della nuova specifica, ma che reputo personalmente di maggior utilità pratica, è la tanto desiderata standardizzazione dei nomi JNDI all’interno di una applicazione JavaEE. Fino a ieri infatti le operazioni di lookup (esplicite o implicitamente eseguite da una annotazione) dovevano essere fatte utilizzando il nome pubblicato con il quale l’oggetto remoto veniva pubblicato nel context JNDI: tale nome, detto anche global JNDI name, è stato spesso in passato oggetto di variazioni e personalizzazioni da parte dei vari produttori di appication server. Anche se non si tratta di un problema insormontabile (è sufficiente consultare la documentazione del prodotto utilizzato) è piuttosto frustrante non poter provare alla prima i propri componenti per un banale errore di sintassi, così come appare bizzaro che la portabilità fra application server sia impedita da un dettaglio così banale.
A conferma di questo strano comportamento, si può prendere a riferimento la tabella di figura 2 dove sono riportate le convenzioni sul naming di un ipotetico session bean con nome userSessionBean (con nome interfaccia remota userSessionRemote) contenuto in una UserApplication.ear:
Come si può notare le differenze sono davvero minime, ma tali da impedire la portabilità del codice e capaci magari provocare qualche mal di testa al programmatore.
Fortunatamente la specifica adesso prevede una unica convenzione sul nome del bean che verrà pubblicato con un nome pubblico che segue questo schema:
java:global[/]//#
L’unico commento che mi viene da aggiungere a questa novità è semplicemente: perche’ abbiamo dovuto aspettare la specifica 3.1? Non è una cosa che andava inserita già dalla release 1.0? Forse mi sono perso qualche motivazione tecnologica o politica che sta sotto questo ritardo. Invito i lettori a darmene notizia se ne fossero a conoscenza.
I nuovi EJB 3 Embeddable Containers per la piattaforma Java SE
Gli application server EJB sono l’habitat dentro il quale viene normalmente eseguita una applicazione EJB e dove si susseguono le varie fasi del suo ciclo di vita. Normalmente si pensa all’application server come a quel complesso strumento la cui gestione richiede risorse di macchina e conoscenze non banali.
In realtà è già da diverso tempo che i vari produttori stanno rilasciando dei container leggeri in grado di essere inseriti all’interno di prodotti più complessi o completi: si pensi al caso di OpenEJB (il motore enterprise di Apache Geronimo e dell’entry level WebSphere Community Edition), al recente EasyBeans (arrivato sul palcoscenico JavaEE dopo una operazione di estrazione da JOnAS).
L’aspetto più importante della specifica EJB 3.1 in materia di enterprise EJB containers è la standardizzazione dei dettagli implementativi di questi oggetti unitamente alla precisa definizione sulle modalità di plugging all’interno di altri ambienti. Per la prima volta si pone molta enfasi sulla possibilità di utilizzare tali motori anche in ambiti non enterprise (JavaSE) semplicemente con l’importazione di una libreria.
A livello di client sarà possibile scrivere una cosa del genere, che fino a poco tempo fa era pura fantascienza:
public class MyClient { public static void main(String[] args) throws Exception { EJBContainer container = EJBContainerFactory.createEJBContainer(); Context context = container.getContext(); MyBean bean = (MyBean) context.lookup("java:global/MyApp/MyBean"); bean.doSomething(); } }
Se da un lato questo approccio semplifica drasticamente lo sviluppo di applicazioni piccole o della prototipizzazione agile, certamente a detta di molti è nella realizzazione di nuovi strumenti di unit test che si potranno trarre i maggiori benefici (per adesso vero tallone di achille delle tecnologie a componenti che prevedano l’uso di un contenitore).
La specifica impone al momento che un container embeddable supporti solamente il set di funzionalità EJB Lite, anche se non è irrealistico che i produttori, con un piccolo ulteriore sforzo, coprano l’intero stack tecnologico.
Conclusione
Presumibilmente, le novità introdotte in questo articolo della serie possono essere considerate di minore importanza rispetto a quanto visto nelle puntate precedenti; questa valutazione è probabilmente corroborata dai fatti, anche se penso che alcune delle cose qui viste (in particolare la possibilità di utilizzare container embedded per la piattaforma SE) potrebbero portare a piccole innovazioni epocali (uno su tutti, il rilascio di un tanto atteso sistema di testing alla JUnit integrato con componenti EJB).
Rimando alla lettura delle prossime serie dedicate alle novità JavaEE 6 e alle nuove specifiche per le tecnologie web (Web Beans e Servlet 3.0) di cui avremo modo di parlare su MokaByte.
Riferimenti
[PROFILES] I nuovi Profili in Java 6
http://weblogs.java.net/blog/robc/archive/2008/02/profiles_in_the_1.html