In questo articolo continueremo a parlare di JBoss Seam, e in particolare di un tool a corredo del framework, utile per la creazione veloce della struttura di un’ applicazione web basata su Seam. Il tool in questione è Seam Gen che, oltre a creare la struttura dell’applicazione, genera anche i file di progetto Eclipse, NetBeans e IDEA per facilitare l’importazione nel proprio IDE preferito.
Introduzione
Seam Gen è un tool che permette di creare rapidamente un progetto Seam funzionale, basato su database, e senza scrivere una riga di codice. Dopo una prima fase di raccolta di informazioni relative all’applicazione da creare, come il nome dell’applicazione e le informazioni per la connessione al database, Seam Gen crea la struttura del progetto basato su Seam. Inoltre, è possibile sfruttare la connessione al database indicato per effettuare un reverse engineering e creare sia il codice necessario ad effettuare le operazioni di creazione, lettura, scrittura e aggiornamento dei records (CRUD), sia le pagine web per interagire con esso da remoto. Grazie a questo tool possiamo creare un’applicazione completamente funzionale che può essere trasferita immediatamente su JBoss AS e che potrà essere personalizzata e arricchita nelle fasi successive per ottenere i risultati desiderati. Insomma, non il classico progetto “Hello World”, bensì molto di più, e senza scrivere una riga di codice.
Approccio di tipo Bottom Up
Consideriamo uno scenario comune in cui l’ azienda che richiede la creazione di un’applicazione web ha già una gestione informatizzata e, come accade molto spesso, basata su database di tipo relazionale contenente le informazioni rilevanti. In uno scenario di questo tipo, l’approccio che si userà sarà di tipo bottom up, dal momento che il database è già esistente e guiderà in larga parte la creazione delle classi Java. Sebbene seam-gen permetta anche l’utilizzo dell’approccio inverso (top down), in cui il database nasce dopo il codice, è proprio col bottom up che dà eccellenti risultati.
Utilizzando Seam Gen possiamo anche capire come i creatori di Seam amino organizzare un progetto e valutare se adottare il loro approccio oppure no. Qualora non si intenda utilizzare tale organizzazione progettuale è sempre possibile modifcare il template per adattarlo alle nostre esigenze, personalizzando il codice generato e sfruttando comunque la comodità del reverse-engineering.
Per comodità di esposizione, partiamo da uno schema abbastanza semplice (e incompleto) di database relazionale:
Figura 1 – Schema per l’applicazione di esempio.
Per lavorare con seam-gen, è necessario digitare seam dalla cartella di installazione di Seam seguito dal nome del comando che si intende eseguire. Per sapere quali comandi possono essere eseguiti possiamo digitare
seam help
e verrà mostrata una breve descrizione di seam-gen e una lunga lista di comandi supportati.
seam (aka seam-gen) - Execute seam code generation. The seam.bat (Windows) and seam (Linux/Unix) scripts support commands that use Ant build targets to set up a Seam project and generate source code. Ant is not required to be on your path to use this script. JBoss AS must be installed to deploy the project (JBoss AS 7.1.1 is strongly recommended). …
I comandi principali
I comandi da lanciare per creare l’applicazione di esempio, che chiameremo Shop84, sono i seguenti:
seam setup
raccoglie informazioni sul progetto da creare e sul database da utilizzare.
seam create-project
viene creato il progetto Shop84.
seam generate
viene effettuato il reverse-engineering del database indicato con seam setup al fine di creare un’applicazione CRUD per gestire le tabelle.
seam explode
viene effettuato il deploy dell’applicazione su JBoss AS come archivio Java EE esploso.
Dopo questi semplici passi, possiamo far partire JBoss AS e possiamo vedere i risultati ottenuti.
Domande e risposte
Quando lanciamo il comando
seam setup
ci vengono poste una serie di domande che permetteranno a seam-gen di raccogliere le informazioni necessarie a creare il progetto. Ogni linea sarà composta da 3 parti:
- la domanda
- il valore corrente
- una lista di risposte valide (quando possibile)
In questa prima fase occorre rispondere ad ogni domanda premendo Enter per passare alla successiva. Parte dell’output relativo a tale comando è riportato di seguito
SEAM_HOME: D:ApplicazioniJavajboss-seam-2.3.0.Final Using seam-gen sources from: D:ApplicazioniJavajboss-seam-2.3.0.Finalseam-gen Buildfile: D:ApplicazioniJavajboss-seam-2.3.0.Finalseam-gen uild.xml init: setup: [echo] Welcome to seam-gen 2.3.0.Final :-) [echo] Answer each question or hit ENTER to accept the default (in brackets) [echo] [input] Enter the directory where you want the project to be created (should not contain spaces) [] D:ApplicazioniJavajboss-seam-2.3.0.FinalProjects [input] Enter your JBoss AS home directory [] [] D:ApplicazioniJavajboss-as-7.1.1.Final ... [input] Enter the project name [myproject] [myproject] Shop84 [echo] Accepted project name as: Shop84 [input] Select a RichFaces skin [blueSky] ([blueSky], emeraldTown, ruby, classic, japanCherry, wine, deepMarine, DEFAULT, plain) [input] Is this project deployed as an EAR (with EJB components) or a WAR (with no EJB support)? [war] (ear, [war]) ear ... [input] What kind of database are you using? [h2] (hsql, mysql, derby, oracle, postgres, mssql, db2, sybase, enterprisedb, [h2]) mysql ... [input] Enter the filesystem path to the JDBC driver jar [] [] D:ApplicazioniJavamysql-connector-java-5.1.22mysql-connector-java-5.1.22-bin.jar ... [input] Enter the JDBC driver class for your database [com.mysql.jdbc.Driver] [com.mysql.jdbc.Driver] [input] Enter the JDBC DataSource class for your database [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] [input] Enter the JDBC URL for your database [jdbc:mysql:///test] [jdbc:mysql:///test] jdbc:mysql://localhost:3306/shopdb [input] Enter the database username [sa] [sa] shopsa [input] Enter the database password [] [] shopsa ... [input] Are you working with tables that already exist in the database? [n](y, [n]) y [input] Do you want to recreate the database tables and execute import.sql each time you deploy? [n] (y, [n]) n [delete] Deleting: D:ApplicazioniJavajboss-seam-2.3.0.Final seam-gen uild.properties [propertyfile] Creating new property file: D:ApplicazioniJavajboss-seam-2.3.0.Final seam-gen uild.properties [echo] Installing JDBC driver jar to JBoss AS [copy] Copying 1 file to D:ApplicazioniJava jboss-as-7.1.1.Finalstandalonedeployments init: init-properties: [echo] D:/Applicazioni/Java/jboss-as-7.1.1.Final validate-workspace: validate-project: settings: [echo] JBoss AS home: D:/Applicazioni/Java/jboss-as-7.1.1.Final [echo] GlassFish home: C:/Program Files/glassfish-v2.1 [echo] Project name: Shop84 [echo] Project location: D:/Applicazioni/Java/jboss-seam-2.3.0.Final/Projects/Shop84 [echo] Project type: ear [echo] IceFaces: ${icefaces.new} [echo] Action package: com.mydomain.Shop84.action [echo] Model package: com.mydomain.Shop84.model [echo] Test package: com.mydomain.Shop84.test [echo] JDBC driver class: com.mysql.jdbc.Driver [echo] JDBC DataSource class: com.mysql.jdbc.jdbc2.optional.MysqlDataSource [echo] Hibernate dialect: org.hibernate.dialect.MySQLDialect [echo] JDBC URL: jdbc:mysql://localhost:3306/shopdb [echo] Database username: shopsa [echo] Database password: shopsa [echo] [echo] Type 'seam create-project' to create the new project BUILD SUCCESSFUL Total time: 3 minutes 19 seconds
Lo scopo del comando seam setup è quello di riempire il file seam-gen/build.properties, sovrascrivendolo se già esiste, con le impostazioni necessarie per creare il progetto. In questo file vengono memorizzate le risposte nel tipico formato Java di file properties, usando coppie key-value. Nel caso in cui non si risponda a una delle domande, o si intenda cambiare il valore precedentemente impostato, sarà sufficiente rilanciare il comando seam setup. Seam infatti ricorda tutte le risposte fornite nella precedente esecuzione e ripropone queste risposte come valori di default che possono essere accettate premendo semplicemente Enter. In alternativa si può modificare direttamente il file seam-gen/build.properties.
Oltre a creare e a popolare il file seam-gen/build.properties, il comando setup copia il driver JDBC in JBoss AS per rendere possibile la connessione al database come data source JCA. Nel nostro caso il driver JDBC MySQL viene copiato nella cartella
${jboss.home}standalonedeployments
e il data source JCA è registrato in JNDI per essere usato dall’unità di persistenza.
Creiamo la struttura del progetto
Con il comando setup abbiamo fornito a seam-gen le informazioni necessarie per creare il template del progetto. Per fare in modo che dal template si passi al progetto vero e proprio dobbiamo eseguire
seam create-project
Con questo comando Seam creerà un nuovo progetto Java nella directory indicata e lo popolerà con tutte le librerie necessarie allo sviluppo di un progetto Seam, completo anche di build Ant per la compilazione, testing, packaging e deploying dell’applicazione. Verranno creati anche i file di progetto per Eclipse, NetBeans e IDEA per permettere una facile importazione all’interno di questi IDE.
Il plugin JBossTools per Eclipse ha un wizard che racchiude tutti questi comandi e permette la creazione di un progetto Seam come un qualunque progetto Java. Tuttavia il progetto che si ottiene tramite questo plugin non è esattamente lo stesso che si crea con i comandi a riga di comando.
Interfaccia CRUD
Con il comando precedente abbiamo creato la struttura base di un progetto pronto per essere trasferita su JBoss AS. Prima di fare questo, sfruttiamo una utilissima caratteristica di seam-gen, ovvero il reverse engineering del DB tramite il comando
seam generate
Con questo comando vengono generate tutte le classi per gli entity direttamente dallo schema del database e anche l’interfaccia CRUD per gestire questi entity attraverso delle view Facelets e delle classi JavaBean.
SEAM_HOME: D:ApplicazioniJavajboss-seam-2.3.0.Final Using seam-gen sources from: D:ApplicazioniJavajboss-seam-2.3.0.Finalseam-ge n Buildfile: D:ApplicazioniJavajboss-seam-2.3.0.Finalseam-gen uild.xml ... generate-model: [echo] Reverse engineering database using JDBC driver D:ApplicazioniJava mysql-connector-java-5.1.22mysql-connector-java-5.1.22-bin.jar [echo] project=D:/Applicazioni/Java/jboss-seam-2.3.0.Final/Projects/Shop84 [echo] model=com.mydomain.Shop84.model [hibernate] Executing Hibernate Tool with a JDBC Configuration (for reverse engineering) ... generate-ui: [echo] Building project 'Shop84' to generate views and controllers init: ... compile: ... copyclasses: ... [hibernate] Executing Hibernate Tool with a JPA Configuration [hibernate] 1. task: generic exportertemplate: view/list.xhtml.ftl [hibernate] 2. task: generic exportertemplate: view/view.xhtml.ftl [hibernate] 3. task: generic exportertemplate: view/view.page.xml.ftl [hibernate] 4. task: generic exportertemplate: view/edit.xhtml.ftl [hibernate] 5. task: generic exportertemplate: view/edit.page.xml.ftl [hibernate] 6. task: generic exportertemplate: src/EntityList.java.ftl [hibernate] 7. task: generic exportertemplate: view/list.page.xml.ftl [hibernate] 8. task: generic exportertemplate: src/EntityHome.java.ftl [hibernate] 9. task: generic exportertemplate: view/layout/menu.xhtml.ftl ...
Deploying del progetto su JBoss AS
Seam-gen crea dei progetti configurati per essere installati su JBoss AS. Quando si effettua il deploying su JBoss AS si può scegliere di inserire il progetto sotto forma di archivio WAR o EAR oppure di inserire lo stesso archivio scompattato, esploso. Nel primo caso occorre lanciare il comando:
seam deploy
che creerà l’archivio in uno dei formati standard Java EE sulla base delle scelte fatte durante la fase di setup. Dopo aver creato l’archivio, verrà spostato nella directory di deployment di JBoss ovvero
${jboss.home}standalonedeployments.
Ecco il codice completo:
SEAM_HOME: D:ApplicazioniJavajboss-seam-2.3.0.Final Using seam-gen sources from: D:ApplicazioniJavajboss-seam-2.3.0.Finalseam-gen Buildfile: D:ApplicazioniJavajboss-seam-2.3.0.Finalseam-gen uild.xml init: ... compile: [javac] Compiling 10 source files to D:ApplicazioniJavajboss-seam-2.3.0.Final ProjectsShop84exploded-archivesShop84.earShop84_jar ... jar: [copy] Copying 1 file to D:ApplicazioniJavajboss-seam-2.3.0.Final ProjectsShop84exploded-archivesShop84.earShop84_jarMETA-INF ... war: [copy] Copying 53 files to D:ApplicazioniJavajboss-seam-2.3.0.Final ProjectsShop84exploded-archivesShop84.earShop84_war ... ear: [copy] Copying 1 file to D:ApplicazioniJavajboss-seam-2.3.0.Final ProjectsShop84exploded-archivesShop84.ear ... datasource: [copy] Copying 1 file to D:ApplicazioniJavajboss-as-7.1.1.Final standalonedeployments deploy: [copy] Copying 1 file to D:ApplicazioniJavajboss-as-7.1.1.Final standalonedeployments BUILD SUCCESSFUL Total time: 17 seconds
Il server JBoss tiene continuamente sotto controllo questa cartella e quando trova un nuovo archivio oppure riscontra dei cambiamenti in archivi esistenti, carica o aggiorna le applicazioni (hot deploy). Allo stesso modo, se un archivio viene rimosso, anche l’applicazione corrispondente verrà rimossa. Nel nostro caso è possibile rimuovere l’applicazione con il comando seam undeploy.
Archivi WAR/EAR vs archivi “esplosi”
Lo svantaggio di usare gli archivi standard WAR ed EAR risiede nel fatto che ogni modifica fatta all’applicazione richiede un ciclo completo di build, package, e deploy. Dalla cartella di JBoss deve quindi essere eliminato il vecchio archivio e sostituito col nuovo per poi dare a JBoss il tempo di ricaricare la nuova applicazione. Questo procedimento fa perdere tanto tempo anche perchè JBoss deve, ogni volta, effettuare lo shut down dei servizi avviati dall’applicazione e farli ripartire dopo aver ricaricato quella nuova. Nel caso di sessioni HTTP avviate e di applicazioni che richiedono autenticazione, è necessario terminare e ricreare altre sessioni HTTP e reinseire le credenziali. Questo ci fa capire come, in fase di sviluppo, il deploying di archivi Java non rappresenta la soluzione migliore e consigliata.
La buona notizia è che esiste una soluzione migliore che consiste nell’effettuare il deploying dell’archivio esploso, ossia il deploying dei file contenuti nell’archivio Java EE in una cartella con lo stesso nome dell’archivio. Questa operazione può essere ottenuta tramite
seam explode
Questo comando è una variante del comando deploy: infatti fa le stesse operazioni di quest’ultimo tranne la creazione di un pacchetto dell’applicazione. L’esecuzione successiva del comando seam explode sincronizzerà solamente i file cambiati, rendendo possibile un aggiornamento incrementale. Questo modo di operare permette, in molti casi, di avere immediatamente disponibili i cambiamenti effettuati ad alcuni file della nostra applicazione senza le perdite di tempo citate in precedenza. Per forzare un reload completo dell’intera applicazione occorre usare il comando seam restart, mentre per rimuovere l’applicazione si usa seam unexplode.
Conclusioni
In questo articolo abbiamo visto un utilissimo strumento facente parte del framework JBoss Seam e abbiamo illustrato i passi da seguire per creare facilmente l’infrastruttura di un’applicazione. Seam-gen rappresenta uno strumento semplice da utilizzare, che si fa carico di molti compiti tediosi, e può costituire una valida modalità operativa per muovere i primi passi con Seam. Inoltre è possibile usarlo sia come strumento a se’, sia in associazione con i più diffusi IDE. Nei prossimi articoli ci addentreremo più a fondo nel progetto, allo scopo di esaminare i vari aspetti del framework Seam.
Riferimenti
[1] Sito di riferimento per il framework Seam
[2] Dan Allen, “Seam in Action”, Manning Publications, 2009
Nato a Vittoria (RG) ha conseguito la laurea in Ingegneria Informatica all’Università di Catania nel luglio del 2003. Si interessa del mondo Java da più di 10 anni e dopo aver lavorato per 3 anni come sviluppatore software su piattaforma J2EE, oggi svolge attività di consulenza e formazione in provincia di Treviso e cura il sito www.tradingonline-news.com