In questo articolo analizzeremo prima di tutto cosa è lo standard Java Platform Enterprise Edition, da quali altri standard è composto e quale può essere una architettura ‘tipo’ di una applicazione basata su Java EE. Inoltre tratteremo delle caretteristiche della versione 6 (JSR-316), rimandando all’articolo successivo per una dettagliata trattazione di alcuni aspetti speficici.
In questo articolo ripercorreremo la storia delle specifiche Java EE dal lontano 1998 fino al 2009, anno dell’ultima stesura. La stesura delle specifiche di Java EE 6, pubblicate a dicembre del 2009 è stata guidata da Roberto Chinnici e Bill Shannon della Sun/Oracle, coadiuvati da un Expert Group che è composto da alcune delle più imporanti aziende del settore IT tra i quali (a parte Sun/Oracle): Red Hat Middleware, IBM, SpringSource, Google ed altri.
Inoltre vedremo quali tecnologie racchiude in se’ e come usarle assieme per progettare una moderna applicazione client/server.
Motivazioni
Le specifiche per una Enterprise Edition di Java furono create nel 1998 per permettere alle imprese, che volevano aumentare le loro possibilità di guadagno investendo su Internet, di ridurre i loro costi e abbassare i tempi di risposta dei loro servizi per i propri clienti, dipendenti e fornitori.
Il problema principale che si posero gli ingegneri della Sun era di incorporare i vecchi Enterprise Information Systems (EISs) con le nuove funzionalità di business che distribuivano servizi a un numero sempre maggiore di clienti.
Questi servizi dovevano soddisfare le seguenti caratteristiche:
- Highly available: dovevano essere servizi sempre disponibili per un grande numero di clienti;
- Security: dovevano essere servizi sicuri per proteggere tramite crittografia i dati dei clienti e dell’azienda;
- Reliable & scalable: dovevano essere dei servizi affidabili (soprattuto per quanto riguarda le transazioni sui database) e scalabili, cioè dovevano offrire le stesse prestazioni sia in caso di un elevato utilizzo (alto numero di connessioni contemporanee da web-client) che in caso di basso utilizzo.
L’architettura originaria
Originariamente si era posto l’accento su una architettura multi-tier di tipo verticale, cioè una architettura in cui i servizi offerti dall’azienda potessero essere distribuiti su più macchine e potessero interoperare tramite un protocollo remoto che potesse serializzare le richieste e le risposte di oggetti Java tra differenti virtual machine. Questo protocollo remoto era da contrappore a CORBA, che invece garantiva l’interoperabilità tra software scritti in linguaggi differenti.
La distribuzione “verticale” dei servizi offerti doveva garantire la scalabilità dei servizi stessi: dato che più servizi potevano essere installati su macchine differenti, il carico massimo di lavoro supportato poteva crescere notevolmente.
Oggi, contrariamente alle architetture distribuite in modo verticale, si preferiscono le architetture scalate in orizzontale, cioè si preferisce distribuire una unica applicazione Java EE su più macchine e permettere ai clienti di poter accedere al nodo più “conveniente” per ogni richiesta (Cloud Computing).
L’architettura verticale non ebbe evidentemente successo, dato che le chiamate a funzione di servizi differenti venivano fatte sempre per copia (le richieste e le risposte dovevano essere serializzate e deserializzate via RMI) e non per riferimento: questo comportava un overhead non trascurabile.
Ricordo che la prima specifica Java EE non prevedeva la possibilità di invocare servizi EJB in maniera locale, ma solo remota. Questo problema fu risolto abbastanza presto tramite l’introduzione delle interfacce locali; inoltre dalla versione 5 del 2006, la Sun ha apportato anche una enorme semplificazione della scrittura e del deploy di servizi EJB.
Vediamo adesso in generale come deve essere architettata una classica applicazione basata su Java EE. Dal punto di vista degli utenti, l’architettura viene vista a due livelli: client (web browser/applet) e server Java EE.
Figura 1 – Architettura client-server.
Dal punto di vista del progettista Java EE, la parte server viene organizzata a più livelli in modo tale da dividere un insieme monolitico di servizi in più parti, logicamente divise tra loro, e tali che il livello n dipenda solo dal livello n-1.
Figura 2 – Esempio di architettura a 3 livelli.
Questa organizzazione a moduli è da sempre stata la caratteristica più importante e innovatrice delle architetture Java nel mondo del web. All’interno della Business Logic possiamo creare ed usare ben più di un EJB, possiamo definire delle dipendenze tra di essi e anche installarli su diversi server Java EE, e renderli residenti anche su diverse macchine fisiche.
Nello schema di figura 3 mettiamo in evidenza sia il tipo di organizzazione fisica dei vari moduli, sia le interfacce esterne (p.e. database o sistemi ereditati accedibili mediante CORBA).
Figura 3 – Architettura Java EE distribuita.
Alcune tappe importanti per giungere a Java EE
Ripercorriamo ora brevemente la storia delle specifiche Java EE. Come si vedrà, il percorso che ha portato alle attuali specifiche è piuttosto lungo e ha anche visto un cambiamento nella denominazione del mondo Java Enterprise. Dall’iniziale Java Professional Edition si è passati attraverso la sigla J2EE per arrivare infine all’attuale Java EE.
Maggio 1998: Java Professional Edition
La prima specifica Java EE prendeva il nome di Java Professional Edition, e fu annunciata da Sun nel 1998. Lo scopo, come già detto, era quello di fornire un pacchetto potente e versatile a quelle aziende che intendevano migliorare la qualità, la sicurezza e la robustezza dei servizi forniti sulla oramai onnipresente rete Internet.
Dicembre 1999: J2EE 1.2
La versione J2EE 1.2 nacque come una specifica che conteneva a ombrello dieci JSR (Java Specification Request). I principali punti della J2EE 1.2 erano:
- Focus sui sistemi distribuiti (multi-tier in verticale, contrapposto alla visione moderna del multi-tier in orizzontale realizzata mediante cloud computing), che lo poneva in competizione con CORBA.
- Enterprise Java Beans (EJBs): Stateful e Stateless Services Objects; Entity EJBs (persistence objects) che erano opzionali; Remote Method Invocation-Internet Inter ORB Protocol (RMI-IIOP) che era obbligatorio, poiche’ non si potevano chiamare i servizi offerti dagli EJB mediante chiamata di funzione, ma solo serializzando e deserializzando gli oggetti Java.
- Servlet e Java Server Pages (JSP).
- JMS per i messaggi asincroni.
Questa prima release non fu accolta con troppo entusiasmo: prima di tutto ci si accorse che l’insistenza del multi-tier distribuito penalizzava fortemente le performance dei sistemi J2EE (mentre la concorrenza .Net non aveva di questi problemi); oltre a ciò gli EJB non erano semplici da scrivere nè da installare (deploy) in un application server.
Settembre 2001: J2EE 1.3
Nella versione 1.3, si introdussero le interfacce locali per poter migliorare le performance. J2EE 1.3, inoltre, viene ricordata per altri aspetti importanti.
- Fu la prima versione sviluppata da un Java Community Process (JSR-58).
- Gli Entity Beans erano ora obbligatori.
- Si introduceva un sistema più semplice per l’installazione degli EJB, basato su un deployment descriptor XML.
- Furono introdotte le interfacce locali che permettevano il passaggio di parametri agli EJB “by reference”.
- Fu introdotta la JCA (J2EE Connector Architecture) per connettere Java EE ai sistemi EIS (Enterprise Information Systems) ereditati.
Il miglioramento introdotto in questa release sulle interfacce locali fu ben accolto; al contrario, però, le specifiche EJB erano ancora troppo complesse per poter essere utilizzate a un basso costo; e inoltre esisteva un grosso problema di compatibilità tra i diversi vendor: un EJB risultava non portabile da un container EJB container a un altro.
Novembre 2003: J2EE 1.4
Nella versione 1.4 (JSR 151) furono introdotte le seguenti componenti:
- supporto per i Web Services: gli EJB 2.1 possono essere invocati su protocollo SOAP/HTTP;
- Timer Service;
- supporto migliorato per il deployment.
Purtroppo, però, la versione 1.4 non risolse i problemi originali di J2EE: la difficoltà incontrata nel costruire un’applicazione basata su J2EE era ancora eccessiva rispetto ai concorrenti che stavano al di fuori del mondo Java (.Net).
Le critiche alle specifiche della Sun non diminuirono affatto; inoltre sempre più professionisti preferivano utilizzare solo alcune parti dello standard e non utilizzare l’intero impianto offerto da un application server; in particolare, in molti rifiutavano di utilizzare lo standard degli EJB, tecnologia centrale per il mercato degli application server.
L’arrivo dei framework
Nel frattempo, nel 2000, un libero professionista che lavorava a Londra, Rod Johnson, iniziava lo sviluppo di Spring. Il lavoro culminò nella stesura del libro “Expert One-on-One Java EE Design and Development” [7] che diventò in breve tempo uno dei libri più importanti per i professionisti del mondo Java. Spring [8] venne rilasciato per la prima volta nel 2003 con l’aiuto di Juergen Hoeller e altri, ed ebbe un successo immediato.
C’è da sottolineare che Spring non fu pensato (nè adottato da tantissimi esperti) come alternativa a J2EE, ma come alternativa solamente alla parte dello standard che riguarda gli EJB. Come ha scritto più volte Rod Johnson, J2EE è differente dagli EJB: gli EJB sono solo una parte dello standard e Spring è un framework basato proprio sullo standard J2EE ed offre a J2EE un sistema di integrazione (glue) di tecnologie alternativo al sistema offerto dagli EJB. Tra l’altro, sin dalle prime versioni di Spring è sempre stato possibile interfacciarsi con degli EJB tramite JNDI, e inoltre una applicazione basata su Spring è perfettamente installabile all’interno di un application server.
Il successo immediato che ebbe Spring diede un colpo enorme alla popolarità degli EJB tanto da far pensare ad un definitivo tramonto degli application server. Infatti molti preferirono soluzioni alternative come l’utilizzo di Tomcat (web server che implementava solo le specifiche delle servlet e delle JSP) con Spring e con un altro software estremamente innovativo e alternativo agli Entity Bean 2.1: Hibernate.
In definitiva, così come Spring rendeva obsoleti i Session Beans, Hibernate rendeva obsoleti gli Entity Bean: mettendo assieme queste due tecnologie, avevamo costruito una infrastruttura flessibile e leggera, alternativa a tutta l’infrastruttura degli EJB, e quindi tutta l’infrastruttura che sta alla base di un application server.
Maggio 2006: Java EE 5
Ma nel 2006 la Sun tenta di far rinascere J2EE (e gli application server) facendo uscire finalmente delle nuove specifiche che rivoluzionarono il mondo degli EJB semplificandoli notevolmente: ora un oggetto EJB è semplicemente un POJO (Plain Old Java Object), proprio come nella visione di Rod Johnson in Spring; si sono eliminati i lunghi file XML di configurazione e il tutto si basa sull’utilizzo delle annotazioni da poco introdotte nel linguaggio Java. La versione 1.5 di J2EE viene ribattezzata Java Enterprise Edition version 5 (Java EE 5) e con questa nuova denominazione verrà proseguita la “serie” numerica delle evoluzioni (con Java EE 6).
Ecco le caratteristiche fondamentali della versione Java EE 5 (JSR 244):
- molte caratteristiche sono ispirate dai framework open source (Spring in particolare);
- gli EJB arrivano alla versione 3.0 e sono basati sui POJO (Plain Old Java Object);
- i metadata possono essere definiti tramite annotazioni piuttosto che via XML;
- introduzione delle Java Server Faces (JSF);
- JAX-WS 2.0 rimpiazza le JAX-RPC per i servizi SOAP.
Contrariamente a quanto si potesse immaginare, queste specifiche ebbero un buon successo: gli EJB (e i corrispondenti application server) tornarono di interesse generale; e tornò anche di interesse generale la storica diatriba: è meglio basarsi su Spring Framework + Tomcat o su un application server?
Inoltre Hibernate influenzò enormemente la scrittura delle nuove specifiche degli Entity Bean: JPA 1.0 è praticamente una standardizzazione delle API di Hibernate. La Sun preferì comunque investire sulla versione free di TopLink di Oracle (ora donata ad Eclipse Foundation) come alternativa a Hibernate e il proprio application server di riferimento, GlassFish, è infatti basato sul nuovo EclipseLink (tutt’oggi EclipseLink è considerato la reference implementation di JPA 2.0). Il lancio della prima versione di GlassFish fu fatto nel 2006 ed era la reference implementation delle specifiche Java EE 5.
Dicembre 2009: Java EE 6
Ora che la semplificazione degli EJB era stata completata con successo, nelle nuove specifiche la Sun pensò bene di continuare su questa linea: per esempio furono definitivamente eliminati gli EJB 2.x (i quali, nella versione Java EE 5, erano ancora obbligatori per preservare gli investimenti fatti dalle aziende sulle specifiche precedenti). In sintesi, nella nuova versione 6 (JSR-316), le caratteristiche salienti erano le seguenti:
- configuration-by-exception per gli EJB e anche per la parte web-tier;
- aggiunta di nuove funzionalità a JPA;
- nuovi servizi web (RESTful) JAX-RS;
- taglio (pruning) degli EJB 2.x;
- introduzione dei profili Web profile e Full profile e definizione degli EJB 3.1 Lite per il profilo Web (praticamente sono stati eliminati gli EJB remoti nella versione Lite);
- Managed Beans;
- JSF 2: una ottima semplificazione dello standard JSF;
- semplificazione del deploy: adesso gli EJB potranno essere distribuiti anche in un WAR e non necessariamente in un EJB-JAR; il packaging EAR oggi è sempre meno usato;
- CDI e DI per facilitare l’integrazione degli EJB con le JSF e, in generale, con qualsiasi tecnologia di vista.
Nella tabella 1, riportiamo l’elenco completo di tutte le tecnologie che vengono incluse dentro “l’ombrello” JSR316 [2]:
Tabella 1 – L’elenco completo delle tecnologie con il riferimento alla specifica.
L’architettura di Java EE 6
L’architettura da seguire per un servizio Java EE 6 può essere analizzata anche dal punto di vista degli standard adoperati: cioè possiamo dividere le unità logiche di business, client e di presentation, in base agli standard che possono essere utilizzati [3]. A tal proposito, riportiamo nella figura 4 lo schema tratto dalle specifiche finali della JSR-316 della Sun/Oracle (nello schema in grigio vengono evidenziate le nuove JSR).
Figura 4 – Java EE 6: Architettura di riferimento.
Si noti come le specifiche Java EE6 non sono tutte presenti nei singoli moduli: per esempio nella parte client non possiamo trovare gli EJB, però troviamo CDI e DI, questo perchè sono due tecnologie che possono funzionare anche al di fuori del contesto di un server certificato Java EE.
Oggi la Sun/Oracle rilascia il proprio server di riferimento GlassFish 3 sia in versione Web profile che Full profile, e sia in versione open source (Open Source Glass Fish) che a pagamento (Oracle Glass Fish). In generale oggi c’è un nuovo interesse attorno agli EJB e soprattutto un buon apprezzamento dello sforzo fatto fin qui dalla Sun per migliorare lo standard.
Le specifiche CDI e DI hanno destato un notevole interesse e sono la vera novità di questa ultima release dello standard. Inoltre il notevole miglioramento delle JSF ha completato l’opera per poter fornire una soluzione “chiavi in mano”, completa e già integrata, di un application server. Questo è diverso dalla soluzione offerta da Spring dove occorre prendere i vari “pezzi ” che ci interessano e integrarli tra loro (per esempio con Jboss abbiamo a disposizione tecnologie come: EJB 3.1, Hibernate, RestEasy, RichFaces già integrate tra loro e pronte all’uso).
Vicerversa con Spring abbiamo sì la difficoltà di dover integrare e scegliere soluzioni diverse che implementano pezzi diversi dello standard, ma in questo modo abbiamo anche il vantaggio di poter utilizzare solo ciò che che ci serve realmente sprecando meno risorse hardware e utilizzando comunque uno standard de facto ben affermato. Inoltre Spring semplifica l’integrazione delle tecnologie più innovative e “richieste” dal mercato anche se non fanno parte dello standard Java EE, come per esempio il mobile (Spring Mobile), Android (Spring Android), filmati flash (Spring Flex), social (Spring Social per Facebook, Flicker o anche Google+), database SQL e NoSQL (Spring Data), etc… Resta quindi il dubbio amletico non ancora risolto: sarà meglio utilizzare Spring o gli EJB?
Conclusioni
Abbiamo terminato una breve presentazione dello standard Java EE 6 e di tutti i suoi componenti, mettendo in evidenza che tipo di architettura software ci si aspetta di progettare quando si lavora con queste tecnologie. Nei prossimi articoli di questa serie su Java EE ci concentreremo in particolare nella sezione “Enterprise Application Technologies” di cui tratteremo le caratteristiche più rilevanti, quali DI [6], CDI [5], EJB 3.1 ed EJB Lite [4].
Riferimenti
[1] Wikipedia, su Java EE
http://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition
[2] Wikipedia, Elenco di tutte le JSR contenute in tutte le versioni di Java EE
http://en.wikipedia.org/wiki/Java_EE_version_history
[3] Sun/Oracle, JSR 316: Java Platform, Enterprise Edition 6 (Java EE 6) Specification
http://jcp.org/en/jsr/detail?id=316
[4] Sun/Oracle, JSR 318: Enterprise JavaBeans 3.1
http://jcp.org/en/jsr/detail?id=318
[5] Sun/Oracle, JSR 299: Contexts and Dependency Injection for the Java EE platform
http://jcp.org/en/jsr/detail?id=318
[6] Sun/Oracle, JSR 330: Dependency Injection for Java
http://jcp.org/en/jsr/detail?id=330
[7] Rod Johnson, Expert One-on-One J2EE Design and Development
http://www.amazon.com/Expert-One-Design-Development-Programmer/dp/0764543857
[8] Spring Framework