Seam è una potente piattaforma di sviluppo open source, basata su Java EE, che permette di implementare Rich Internet Application con semplicità. Essa permette agli sviluppatori di assemblare complesse applicazioni web usando le Annotazioni, un ricco set di componenti UI, e pochissimo XML: non male come premesse.
Introduzione
Seam è una potente piattaforma di sviluppo open source, basata su Java EE, che permette di implementare Rich Internet Application con semplicità. Essa integra tecnologie come Asynchronous JavaScript and XML (AJAX), JavaServer Faces (JSF), Java Persistence (JPA), Enterprise Java Beans (EJB 3.0) e Business Process Management (BPM) in un’unica soluzione. In genere gli sviluppatori impiegano la maggior parte del tempo cercando di integrare tecnologie molto differenti fra loro, scontrandosi con problemi che poco hanno a che vedere con la business logic dell’applicazione. Seam è stata progettata da zero per eliminare la complessità legata a questi compiti non cruciali. Essa permette agli sviluppatori di assemblare complesse applicazioni web usando le Annotazioni, un ricco set di componenti UI, e pochissimo XML, eliminando i livelli di complessità e le configurazioni non necessarie. Inoltre molte delle idee originate nell’ecosistema Seam sono state un valido contributo per le nuove specifiche Java EE.
Perchè Seam?
In un mondo pieno di web framework Java oriented, perchè scegliere Seam? La risposta è la seguente: se si è alla ricerca di un framework potente e leggero che permetta di integrare diverse tecnologie Java in un unico modello concettuale, allora Seam è la soluzione giusta. Definire Seam un web framework allo stesso livello di tanti altri framework Java, è però riduttivo. Seam infatti offre, oltre a un framework vero e proprio, anche delle librerie, script e generatore di progetti, plugin di integrazione con i principali IDE e con diverse tecnologie.
Per capire il perchè è nato JBoss Seam, dobbiamo considerare la situazione esistente con le specifiche Java EE 5. In esse erano presenti due componenti architetturali chiave, le Java Server Faces (JSF) come presentation framework, e gli Enterprise JavaBeans 3 (EJB 3) come modello lato server per la creazione di business component sicuri e scalabili. Per far lavorare assieme le due architetture era necessario codice Java e XML ad hoc. Seam nacque con questo obiettivo: diventare un ponte naturale tra i due framework e fungere da prototipo per le future specifiche della Java EE.
Tecnologie integrate e versatilità
Sappiamo che gli EJB non possono essere legati direttamente a una vista JSF perchè sono componenti completamente isolati dal web tier accessibile attraverso l’azione dei backing bean. Essi non possono accedere ai dati memorizzati in nessuno degli scope del web-tier (request, session, application), e nemmeno accedere al JSF component tree. Questo isolamento limita la loro utilità all’interno di un’applicazione web.
Con Seam, gli EJB 3 hanno l’accesso agli scope del web-tier e le JSF l’accesso ai componenti del business-tier. Inoltre è possibile usare gli EJB 3 come dei Backing Bean e Action Listener, eliminando la necessità di usare un livello Facade.
Sebbene questo possa sembrare una cattiva idea perchè rompe l’isolamento tra i tier che compongono l’applicazione, Seam si pone in mezzo ai vari componenti garantendo un certo grado di disaccoppiamento: tutti i risultati possono essere dei valori logici che Seam interpreterà opportunamente garantendo la separazione tra i vari livelli.
Nonostante ciò Seam non è strettamente legato alle JSF e agli EJB 3; infatti è possibile configurarlo per utilizzare altre tecnologie di presentazione in viste, come Wicket, Tapestry, GWT o Flex al posto delle JSF, e altri modelli lato server, come ad esempio lo Spring Container al posto degli EJB 3. Ma Seam fa molto di più: integra JPA e Hibernate3 per la persistenza, EJB Timer Service e Quartz per l’asincronicità, jBPM per i workflow, JBoss Rules per le regole di business, Meldware Mail per le email, Hibernate Search e Lucene per la ricerca full text, JMS per la messaggistica e JBoss Cache per il caching delle pagine. Pone un framework di sicurezza basato sulle regole sopra JAAS JBoss Rules. Ci sono anche le librerie JSP per la creazione dei PDF, le mail in uscita, i grafici e il testo wiki. I componenti Seam possono essere chiamati in modo sincrono come un Web Service, oppure in modo asincrono da JavaScript lato client o da Google Web Toolkit o, sicuramente, direttamente da JSF. Per questo motivo Seam può essere visto anche come uno strumento di integrazione tra tecnologie diverse.
Le caratteristiche principali
Seam ha rivitalizzato lo standard Java EE rendendo più semplice l’interoperabilità dei suoi componenti in maniera tale da permettere agli sviluppatori di focalizzare le loro energie nella costruzione dell’applicazione e non nell’integrazione delle tecnologie.
Quando si progetta un’applicazione Seam, è necessario scegliere solamente uno State Provider, ossia la tecnologia per gestire la logica dell’applicazione e la risposta agli eventi dell’interfaccia, e un Persistence Provider, ossia la tecnologia per salvare e ritrovare le informazioni. Come detto in precedenza, Seam non richiede l’uso degli EJB 3, per cui con il termine JavaBean includiamo tutti i componenti non EJB. Possiamo ad esempio usare gli Spring Beans assieme a Hibernate, senza perdere in funzionalità.
Figura 1 – Approccio per l’integrazione.
Analizziamo ora le caratteristiche principali di Seam.
Contextual Component Model
Seam definisce un modello uniforme a componenti. Può essere pensato come una fabbrica di componenti (EJB, JavaBenas, Spring Beans, ecc…) che vengono memorizzati in contesti ben definiti caratterizzati da diversi lifetimes, rendendoli di fatto oggetti stateful e creando quindi uno stato per l’intera applicazione. I contesti usati da Seam sono quelli classici della specifica servlet (richiesta, sessione, applicazione), più due nuovi contesti (conversazione e processo di business), che sono più significativi dal punto di vista della logica di business.
Seam tiene traccia di tutti i componenti attraverso un registro centrale e qualsiasi tecnologia inclusa nello stack di Seam può effettuare una ricerca in tale registro per ritrovare i componenti desiderati e interagire con loro. Non c’è alcuna distinzione in Seam tra i componenti del livello presentazione e i componenti di business logic.
Preferenza delle annotazioni all’XML
Sebbene l’XML sia uno strumento molto flessibile, utilizzare dei file di configurazione esterni è un lavoro oneroso a causa della necessità di tenere questi file sempre sincronizzati col codice vero e proprio. Seam permette di eliminare l’XML non necessario attraverso l’uso delle annotazioni Java 5 per tutti i componenti, siano essi EJB 3 che JSF, o altro. Le annotazioni sono solo un modo più conciso e facile da manutere per configurare componenti e servizi. In Seam rappresentano una parte centrale e per limitare al massimo il lavoro di configurazione: ogni componente Seam nasce con un comportamento tipico, per cui sarà necessario usare le annotazioni (o la configurazione tramite XML) solamente quando diventa necessario modificare qualche aspetto e configurarlo in maniera differente. Questo modo di operare viene definito Configuration By Exception.
Unified EL
L’EL è la sintassi usata per risolvere le variabili e legare i componenti alle proprietà e ai metodi dei JavaBeans. Fu introdotto per facilitare l’integrazione tra JSF e JSP, per facilitare la ricerca di managed beans e per essere la base del meccanismo di binding delle JSF. Sebbene usato solo nei componenti del Front View, non c’è nessuna specifica che vieta di usarlo altrove. E infatti Seam prende vantaggio dall’EL in due modi. Prima di tutto registra un proprio resolver EL che è consapevole dell’esistenza del Seam Container, permettendo a tutti i seam component di essere rintracciati da qualsiasi parte dell’applicazione ove è possibile usare la notazione EL. Poi Seam fa un pesante uso della notazione EL nelle annotazioni, nei descrittori, log, nelle stringhe dei messaggi, nelle query Java Persistence Query Language, nella definizione del flusso delle pagine, e persino nei business process.
Testing senza deploying
Testare un’applicazione Java è un processo costoso in quanto richiede la creazione del package e il deploying sul server. Per risolvere questo problema i programmatori hanno adottato il modello di programmazione POJO, che incoraggia la progettazione del codice in modo tale da poter essere testato isolatamente dal container e dai suoi servizi. Questo però non assicura che i componenti lavorino bene insieme in un ambiente reale: è necessario di nuovo effettuare il package dell’applicazione e il deploying in un container. Seam permette di risolvere questa problematica. Infatti, per supportare i test di integrazione, Seam possiede una propria infrastruttura di testing comprendente un Embedded JBoss Container dotato dei seguenti servizi: JNDI, JTA, JCA e JMS. Con questi servizi disponibili, si potranno facilmente scrivere test JUnit o TestNG che riproducano tutta l’interazione con l’utente, verificando tutti i componenti del sistema separati dalla vista (pagina JSP o Facelet). Si potranno eseguire questi test direttamente dentro il proprio IDE, dove Seam automaticamente eseguirà il deploy dei componenti EJB.
Bijection
L’inversione di controllo (IoC) è un pattern che permette di accoppiare debolmente i componenti, consentendo ai componenti di concentrarsi sull’uso dei servizi anzichè sulla loro localizzazione. La Dependency Injection (DI) realizza un’inversione di controllo e viene usata molto in un modello di programmazione POJO per ottenere un accoppiamento debole. Essa viene usata per stabilire, durante la fase di istanziazione, i riferimenti di un componente verso gli oggetti dipendenti (bean wiring). Questa strategia, pur eliminando i lookup, ha qualche limitazione. La più importante è sicuramente la staticità: infatti i componenti vengono injected nella fase di istanziazione senza essere aggiornati successivamente. Inoltre non esiste un meccanismo che permetta di fare il passaggio inverso, cioè aggiornare lo stato del container trasferendo ad esso lo stato corrente del componente. Per superare queste limitazioni, Seam ha introdotto la Bijection che a differenza della DI è dinamica, contestuale e bidirezionale. Il wiring degli oggetti viene fatto durante tutta la vita dell’istanza del componente, e oltre alla injection è prevista anche la outjection per trasferire lo stato del componente al container e da qui essere usato dagli altri componenti.
AJAX integrato
Seam supporta le migliori soluzioni open source AJAX basate su JSF: JBoss RichFaces e ICEFaces. Queste soluzioni permettono di aggiungere funzionalità AJAX all’interfaccia utente senza il bisogno di scrivere codice JavaScript. In alternativa Seam fornisce al suo interno uno strato remoto di JavaScript che consente di chiamare i componenti in modo asincrono da JavaScript lato client senza il bisogno di uno strato di azione intermedio. Si può anche sottoscrivere topic JMS lato server e ricevere messaggi tramite push AJAX. Nessuno di questi approcci funzionerebbe bene, se non fosse per la gestione interna di Seam della concorrenza e dello stato, la quale assicura che molte richieste AJAX a grana fine (fine-grained) concorrenti e asincrone vengano gestite in modo sicuro e efficiente lato server.
Conclusioni
In questo primo articolo abbiamo fatto una breve panoramica su JBoss Seam e ne abbiamo illustrato le principali caratteristiche. Nei prossimi articoli esamineremo più a fondo i vari aspetti che rendono veramente interessante questo prodotto come soluzione per creare delle applicazioni Java Oriented robuste e complete.
Riferimenti
[1] Sito di riferimento per il Framework Seam
[2] Dan Allen, “Seam in Action”, Manning Publications, 2009