Spring Roo: un RAD per Java EE

II parte: Nuove funzionalità di Spring Roo e integrazione con Cloud Foundrydi

Spring Roo è uno strumento web-RAD per applicazioni Java EE basate su Spring: permette di scrivere velocemente il prototipo di una applicazione web e di un web-CRUD in meno di 10 minuti. Se a questo aggiungiamo che si integra facilmente con Cloud Foundry di VMware' bè le ragioni per prenderlo in considerazione ci sono tutte.

Nuove funzionalità per Spring Roo

Dalla nuova versione di Spring Roo, 1.2.0, sono state introdotte delle funzionalità molto importanti che permettono di avere un approccio "più pragmatico", quali:

  1. incremental DataBase Reverse Engineering (DBRE);
  2. supporto per JSF tramite PrimeFaces;
  3. supporto al progetto multi-modulo.

Il supporto per le JSF tramite PrimeFaces è importante per poter usare Roo con le nuove tecnologie vista; purtroppo però questo plugin non sembra ancora al livello del plugin per le JSP.

Per quanto riguarda le altre due migliorie, esse sono molto utili e permettono di avere un approccio più pragmatico nella creazione di un progetto Java EE.

Infatti appare poco realistico il dover creare a mano gli entity beans tramite i comandi entity e field; invece è più corretto creare dapprima il database, e poi effettuare un reverse engineering ottenendo gli entity bean risultanti.

Il plugin DBRE di Spring Roo permette non solo di effettuare il reverse engineering "a freddo", cioè alla creazione del progetto, ma permette anche di tenere aggiornato il progetto a seguito di cambiamenti dello schema del DB. In pratica, se si aggiunge una colonna a una tabella Roo, se ne accorge e fa la stessa modifica sul codice Java.

Il supporto multi-modulo è molto utile per poter organizzare in modo razionale un progetto multi-layer: infatti per convenzione un progetto Java EE è diviso almeno nei moduli di core e web.

Core è il modulo in cui sono contenute tutte le classi che permettono l'accesso al DB; inoltre sono contenute anche le funzionalità di base sul DB. Inoltre in questo modulo vengono implementati i servizi relativi agli entity bean.

Web: è la parte dove si trovano le pagine web.

Questo schema riflette l'architettura tipica di un progetto Spring Roo. Ci sembra quindi opportuno seguire la stessa demarcazione anche nella organizzazione dei sotto-moduli Maven del progetto.

Esempio di utilizzo delle nuove funzionalità di Spring Roo

Supponiamo di dover implementare un sito web di prenotazione a un ristorante. Quello che vogliamo fare è un prototipo che implementi solamente il CRUD sul database già preesistente. Supponiamo, in maniera molto lineare, che il DB sia un server MySQL.

Il progetto sarà diviso in:

  1. modulo principale: è un progetto di tipo POM;
  2. modulo di persistenza e servizi: è un progetto di tipo JAR;
  3. modulo web: è di tipo WAR.

Creazione di un progetto modulare

Supponiamo di avere le tabelle già create dentro un databaes MySQL. Adesso iniziamo a creare il nostro progetto Java EE sul DB preesistente. Per creare un progetto modulare basta usare il comando module. Creiamo dapprima il progetto root di tipo POM, poi subito dopo creiamo il modulo core:

roo> project --topLevelPackage org.mokabyte --packaging  POM
roo> module create --moduleName core --topLevelPackage ~.core

A questo punto definiamo il database da usare tramite il seguente comando:

roo> jpa setup --provider HIBERNATE --database MYSQL --hostName localhost 
     --userName root --password 12qwas --databaseName mokabyte

Adesso occorre effettuare il reverse engineering dal DB (durante tutte le operazioni che seguono il DB deve essere acceso e accessibile).

Installazione dei driver per MySQL

Prima di poter effettuare il reverse engineering da un database è necessario installare i driver e i moduli OSGi che servono a Roo per integrarlo. Questo processo è ben documentato ed è automatico per i database OpenSource; ovviamente, per database proprietari, come Oracle, il driver non è presente nei repository Maven di SpringSource, quindi è necessario fare dei passi a mano (peraltro molto semplici e ben documentati).

Prima di tutto occorre eseguire il comando di introspezione del database per poter capire che tipo di DB è (ecco perchè il DB deve essere acceso):

roo> database introspect --schema no-schema-required
Located add-on that may offer this JDBC driver
1 found, sorted by rank; T = trusted developer; R = Roo 1.1 compatible
ID T R DESCRIPTION -------------------------------------------------------------
01 Y Y 5.1.13.0001 #jdbcdriver driverclass:com.mysql.jdbc.Driver. This...
--------------------------------------------------------------------------------
[HINT] use 'addon info id --searchResultId ..' to see details about a search result
[HINT] use 'addon install id --searchResultId ..' to install a specific search result, or
[HINT] use 'addon install bundle --bundleSymbolicName TAB' to install a specific add-on version
JDBC driver not available for 'com.mysql.jdbc.Driver'

Roo "ha capito" che abbiamo a che fare con MySql, e adesso occorre aggiungere il driver trovato tramite il comando:

addon install id --searchResultId 01

Invece il comando :

addon info id --searchResultId 01

restituisce le informazioni sulla versione del driver disponibile.

Ora il driver per MySql è installato correttamente, quindi possiamo inviare il comando di reverse engineering:

core roo> database reverse engineer --schema mokabyte --package ~.DB --testAutomatically
Created core|SRC_MAIN_RESOURCES/dbre.xml
Updated core|ROOT/pom.xml
Updated core|SRC_MAIN_RESOURCES/META-INF/persistence.xml
Created core|SRC_MAIN_JAVA/org/mokabyte/core/DB
Created core|SRC_MAIN_JAVA/org/mokabyte/core/DB/Menu.java
Created core|SRC_MAIN_JAVA/org/mokabyte/core/DB/Ordinazioni.java
Created core|SRC_MAIN_JAVA/org/mokabyte/core/DB/OrdinazioniPietanza.java
Created core|SRC_MAIN_JAVA/org/mokabyte/core/DB/Pietanze.java
Created core|SRC_MAIN_JAVA/org/mokabyte/core/DB/PietanzeMenu.java
Created core|SRC_MAIN_JAVA/org/mokabyte/core/DB/Tavoli.java
Created core|SRC_MAIN_JAVA/org/mokabyte/core/DB/TipoPietanza.java
Created core|SRC_TEST_JAVA/org/mokabyte/core/DB
Created core|SRC_TEST_JAVA/org/mokabyte/core/DB/MenuDataOnDemand.java
Created core|SRC_TEST_JAVA/org/mokabyte/core/DB/MenuIntegrationTest.java
...

A questo punto abbiamo già pronta la parte CRUD e lo scheletro del progetto Java EE senza dover scrivere neanche una riga di codice!

Finders e Web

Aggiungiamo dei "finders" opportuni agli entity beans trovati. Per esempio, dalla tabella delle Pietanze, vogliamo un metodo di ricerca che ci restituisca tutte le pietanze per nome:

finder add --finderName findPietanzesByNomeLike --class ~.DB.Pietanze

oppure anche:

finder add --finderName findPietanzesByNomeEquals --class ~.DB.Pietanze

In base al nome del finder (il nome è convenzionale), Roo capisce che tipo di finder vogliamo creare, e scriverà la query correttamente per noi. I finders vengono aggiunti all'entity bean tramite annotazioni specifiche che permettono di arricchire l'entity bean.

Servizi

Una volta creati i finders, possiamo creare i nostri servizi. Per esempio creiamo il nostro servizio per Pietanze:

service roo> service --interface ~.service.PietanzeService   --entity ~.DB.Pietanze

Allo stesso modo creiamo il layer web e aggiungiamo il CRUD basato su JSP con gli stessi comandi che abbiamo visto nell'esempio precedente. Allegato a questo articolo (menu in a destra a lato della pagina) troverete gli script MySQL per creare il database di questo esempio e lo script roo "loggato" da Roo stesso.

Test

Spring Roo permette anche la creazione e l'esecuzione automatica dei test sia a livello DB (nel modulo della persistenza) che a livello web, tramite la libreria Selenium che permette di simulare l'utilizzo delle pagine web. Per creare i test unitari e di integrazione basta creare gli entity con il parametro

--testAutomatically

da dare al comando di reverse engineering del DB.

Per ogni entity bean, Roo genera i file DataOnDemand e IntegrationTest che servono per effettuare il test CRUD sull'entity bean e per implementare dei test di integrazione più specifici per il progetto (qui è lo sviluppatore che scrive i propri test di integrazione).

Per esempio Roo ha creato i file PietanzeDataOnDemand.java e PietanzeIntegrationTest.java. I test vengono eseguiti automaticamente da maven. Per la parte web possiamo generare automaticamente uno scaffold via web:

roo>controller scaffold ~.web.ScaffondController

Il controller viene creato utilizzando il supporto REST, e possono essere utilizzati come template per implementare un proprio controller. Ora agganciamoci un test Selenium:

roo>selenium test -controller ~.web.ScaffonldController

ed eseguiamo i test:

roo>perform test

Cloud Foundry

Cloud Foundry è un nuovo PaaS (Platform as a Service) open source rilasciato da VMware. Con Spring Roo è possibile eseguire dei comandi direttamente dalla propria shell: in questa maniera le funzionalità di Cloud Foundry sono immediatamente disponibili. Ciò che si può fare è: loggarsi alla shell di Cloud Foundry, vedere quali sono i servizi installati, effettuare il deploy di un servizio e raccogliere statistiche.

Prima di tutto occorre installare l'add-on per Cloud Foundry tramite i seguenti comandi:

pgp automatic trust
addon install bundle --bundleSymbolicName org.springframework.roo.addon.cloud.foundry

Dopo aver installato l'add-on, è necessario loggarsi alla propria cloud tramite il comando login:

cloud foundry login

Questo comando prende tre parametri in input: email, password, cloudControllerUrl (URL del controller di cloud foundry). email e password corrispondono alle proprie credenziali, e vengono formite solamente la prima volta che ci si connette alla Cloud Foundry. Invece l'Url del controller della Cloud Foundry non è obbligatorio, ma è necessario inserirla per utilizzare una propria cloud foundry locale privata invece di quella fornita di default da VMware (api.cloudfoundry.com).

Per vedere i comandi disponibili per accedere alla Cloud Foundry occorre scrivere cloud foundry e poi premere TAB: nella shell di Roo comparirà la seguente lista di comandi:

    roo> cloud foundry                                                    
        cloud foundry bind       cloud foundry clear      cloud foundry create    
        cloud foundry delete     cloud foundry deploy     cloud foundry files
        cloud foundry info       cloud foundry list       cloud foundry login     
        cloud foundry map        cloud foundry restart    cloud foundry start
        cloud foundry stop       cloud foundry unbind     cloud foundry unmap     
        cloud foundry update     cloud foundry view

Per vedere le informazioni associate alla nostra istanza di Cloud Foundry, digitate il comando info:

    roo> cloud foundry info
           VMwarès Cloud Application Platform
           For support visit support@cloudfoundry.com
           Target:     http://api.cloudfoundry.com (0.999)
           User:     my-mail@gmail.com
           Usage:     Memory (0MB of 2048MB total)
           Services (0 of 16 total)
           Apps (0 of 20 total)

Il comando info ci dà informazioni sull'uso della memoria, il numero di applicazioni ditribuite e il numero di servizi che stanno in esecuzione. Inoltre viene specificato il limite di memoria imposto: 2 gigabyte.

Il deploy del WAR

Una volta loggati alla propria Cloud Foundry, possiamo effettuare il deploy di un WAR tramite il comando:

cloud foundry deploy

I parametri da dare al comando di deploy sono: appName, path, url e quantità di memoria da poter usare. Se il WAR dell'applicazione non è ancora disponibile, allora Roo lo creerà utilizzando Maven come configurato dal progetto Roo. Ecco un esempio:

cloud foundry deploy --appName my-web-app --path
        /target/my-web-app-0.1.0.BUILD-SNAPSHOT.war --memory 512MB

Una volta creata l'applicazione, essa è visibile tramite il comando:

cloud foundry list apps

Su una instanza di Cloud Foundry, possiamo utilizzare un numero limitato di servizi, come per esempio: MySQL, MongoDB Redis e RabbitMQ. Per sapere la lista di servizi supportati (application service) basta digitare il comando:

cloud foundry list service

Per ora la lista di servizi supportati è limitata, ma in futuro verranno inclusi sempre nuovi servizi. Per quanto riguarda la tecnologia Java, possiamo quindi usare solamente il database MySQL come supporto SQL (su Cloud Foundry possiamo installare non solo applicazioni Java, ma anche applicazioni scritte in altri linguaggi, come Scala, Ruby e altri), quindi nel nostro progetto Roo dobbiamo per forza scegliere MySql come provider di persistenza Sql:

persistence setup --database MYSQL --provider HIBERNATE

In questo esempio abbiamo scelto di usare Hibernate, ma avremmo potuto anche usare EclipseLink. Una volta certi che il nostro WAR utilizzi MySql, creiamo il servizio MySql e leghiamolo alla nostra applicazioni web:

cloud foundry create service --serviceName my-web-app-DB --serviceType mysql
cloud foundry bind service --appName my-web-app --serviceName  my-web-app-DB

Tramite il primo comando abbiamo creato il servizio MySql (e chiamato my-web-app-DB), e tramite il secondo comando l'abbiamo legato alla nostra applicazione (e reso disponibile all'interno del Cloud Foundry).

A questo punto possiamo far partire la nostra applicazione web tramite il comando:

cloud foundry start app --appName my-wen-app

Ed infine ecco la lista di applicazioni installate:

roo> cloud foundry list apps                     
================================= Applications =================================
Name        Status    Instances   Services        URLs
----        ------    ---------   --------        ----
my-web-app  STARTED   1           my-web-app-DB   my-web-app.cloudfoundry.com
 
roo> cloud foundry list services
================== System Services ===================
Service     Version     Description
-------     -------     -----------
mongodb     1.8         MongoDB NoSQL store
redis       2.2         Redis key-value store service
mysql       5.1         MySQL database service
 
= Provisioned Services =
Name              Service
----              -------
my-web-app-DB     mysql

Conclusioni

Abbiamo concluso questa serie di articoli introduttivi a Spring Roo: abbiamo cercato di metterne in evidenza i benefici che possiamo guadagnare da questo strumento. In conclusione non c'è nulla che non si possa fare senza Spring Roo: è sempre possibile scrivere un prototipo velocemente senza utilizzare Spring Roo, così come è sempre possibile usare i comandi di Cloud Foundry senza utilizzare la shell di Roo.

Quindi Spring Roo non aggiunge nulla di nuovo a quello che potevamo fare già prima, non solo: Spring Roo non è da usare per imparare tecnologie nuove. Quindi non è affatto uno strumento didattico: al contrario, occorre essere esperti delle tecnologie che stiamo usando per poterle poi utilizzare al meglio dentro la schell di Spring Roo.

Quindi perchè usare Spring Roo? La risposta sta nella possibilità di poter automatizzare i primi passi di scrittura di un prototipo (o di una applicazione finita) Java EE basata su Spring e di poter utilizzare assieme diverse tecnologie senza alcun bisogno di scrivere  codice e/o configurazioni personalizzate, e quindi senza doversi reinventare ogni volta delle proprie convenzioni ma utilizzando quelle standard stabilite proprio dagli autori di Spring Framework.

Riferimenti

[1] Search Software Quality

http://searchsoftwarequality.techtarget.com/definition/rapid-application-development

 

[2] Wikipedia sul "convention over configuration" principle

http://en.wikipedia.org/wiki/Convention_over_configuration

 

[3] Wikipedia propone una lista di strumenti RAD

http://en.wikipedia.org/wiki/List_of_rapid_application_development_tools

 

[4] Wikipedia sul "delegation pattern", utilizzato per implementare il JpaRepository

http://en.wikipedia.org/wiki/Delegation_pattern

 

[5] La libreria Spring Data è un progetto che contiene tutti i sotto progetti che permettono l'accesso a data storage di diverso tipo e tramite specifiche tecniche, tra i quali JDBC, JPA, MongoDB, Hadoop, Neo4j, etc...

http://www.springsource.org/spring-data

 

[6] MongoDB home page

http://www.mongodb.org/

 

[7] Home Pages di diverse tecnologie web:

Prime Faces

http://www.primefaces.org/

 

Vaadin

https://vaadin.com/home

 

Spring Web Flow: che è una estenzione di Spring MVC. Supporta le JSP, JSF e le Portlet.

http://www.springsource.org/spring-web-flow

 

Progetto Spring-Flex per il supporto ad Adobe Flex

http://www.springsource.org/spring-flex

 

[8] Sono da leggere una serie di articoli sul sito dell'IBM su Spring Roo che trattano di temi quali: come scrivere degli add-ons o come integrare Roo con Clound Foundry.

 

Building from source

http://www.ibm.com/developerworks/opensource/library/os-springroo1/index.html

 

Developing an application with Spring Roo

http://www.ibm.com/developerworks/opensource/library/os-springroo2/index.html

 

Developing Spring Roo add-ons

http://www.ibm.com/developerworks/opensource/library/os-springroo3/index.html

 

Rapid application development in cloud with Spring Roo and Cloud Foundry

http://www.ibm.com/developerworks/opensource/library/os-springroo4/index.html

 

[9] Twitter su Spring Roo

https://twitter.com/#!/SpringRoo

 

[10] Aspectj sul Web.

AspectJ era un vecchio progetto di Xerox, poi donato a Eclipse: è stato il primo progetto Java di implementazione del paradigma degli aspetti (AOP: Aspect Oriented Programming). Attualmente il leader del progetto AspectJ è Adrian Colyer, CTO di SpringSource.

http://www.eclipse.org/aspectj/doc/next/progguide/index.html

http://it.wikipedia.org/wiki/AspectJ

http://en.wikipedia.org/wiki/PARC_%28company%29

 

Condividi

Pubblicato nel numero
173 maggio 2012
Michele Mazzei si è laureato in Scienze dell’Informazione nell’ormai lontano 1998. Si occupa di progettazione e scrittura di software in Java/Java EE e in C/C++ sul mondo Linux. Lavora a Roma in ambito spaziale maturando esperienze in ambito OGC, GIS, Map Server, Payload Data Ground Segment (PDGS). Si interessa di…
Articoli nella stessa serie
Ti potrebbe interessare anche