Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Cap5 RapidApplicationDevelopmentfortheCloud
Cap5 RapidApplicationDevelopmentfortheCloud
RIFERIMENTI
Introduzione
“Le Rich Internet Application (RIA) sono applicazioni web che possiedono le caratteristiche e le
funzionalità delle applicazioni desktop, senza però necessitare dell'installazione sul disco fisso.
Le RIA si caratterizzano per la dimensione interattiva, la multimedialità e per la velocità
d'esecuzione. Infatti la parte dell'applicazione che elabora i dati è trasferita a livello client e fornisce
una pronta risposta all'interfaccia utente, mentre la gran parte dei dati e dell'applicazione rimane
sul server remoto, con notevole alleggerimento per il computer utente. Le RIA si fondano perciò su
un'architettura di tipo distribuito.
Anche l'interazione con una RIA avviene in remoto, tramite un comune web browser.
In un certo senso le RIA rappresentano una generazione di applicazioni che permette
un'interazione totalmente rinnovata, fondata sugli aspetti migliori delle caratteristiche funzionali e
progettuali che finora erano prerogativa alternata del web o delle applicazioni desktop.
Inoltre le RIA, per il livello spinto di interattività che esse offrono, rappresentano uno dei canali
migliori attraverso il quale si va imponendo il paradigma del Cloud Computing, che costituisce una
nuova modalità di fruizione del software tramite architetture distribuite.” da wikipedia
Nei capitoli precedenti si sono introdotte quattro differenti tecnologie, ognuna delle quali riguardante
uno specifico settore:
L’obiettivo di questo capitolo sarà quello di riuscire a far interagire tra loro gli strumenti sopra
indicati, in maniera tale da poterli utilizzare per lo sviluppo di applicazioni di tipo RIA. Si partirà dalla
costruzione dell’ambiente di sviluppo, fino ad arrivare alla creazione di una semplice applicazione
d’esempio. Le metodologie di integrazione elencate nelle sezioni successive, non sono da riternersi
le uniche possibili. Ad ogni integrazione verrà indicata la motivazione della scelta fatta, dove
saranno disponibili più opzioni.
MASHUP, enough talk, lets get our hands dirty!
IDE ECLIPSE
Come ambiente di sviluppo è stato scelto Eclipse, poichè la sua grande disponibilità di plugin e
componenti aggiuntivi, rendono questo strumento poliedrico e il più utilizzato in ambienti di sviluppo
Java e non.
- http://code.google.com/intl/it-IT/webtoolkit/download.html
per l’installzione seguire la procedura indicata in “Passi per l’istallazione” di Maven
nel paragrafo successivo.
Rispettivamente partendo da sinistra, il tasto per la creazioni di applicazioni GWT, il tasto per la
compilazione e il tasto per la pubblicazione sul Google Engine.
MAVEN
per l’integrazione dello strumento Maven all’interno del nostro IDE, è necessario installare il plugin
corrispondente m2eclipse reperibile al sito:
- http://m2eclipse.sonatype.org/sites/m2e
Passi per l’installazione:
1. Selezionare Help > Install New Software dal menu di Eclipse, così facendo si aprirà
una finestra di dialogo con dei campi da inserire.
2. Inserire il link sopra elencato nell’apposita casella "Work with:" and press invio.
Dopo la pressione del tasto verranno visualizzati i plugin corrispondenti e i relativi
aggiornamenti.
3. Scegliere il componente elencato sotto m2eclipse: "Maven Integration for Eclipse
(Required)".
4.Click su Next. Eclipse effettuerà un test per verificare la buona riuscita
dell’installazione.
5. Click su Next e accettare la Eclipse Public License v1.0.
Dopo aver riavviato l’IDE potremmo aprire un nuovo progetto Maven tramite File->New-
>Other... Maven Project
Da questo momento in poi per la gestione delle dipendenze, utilizzerò sempre il repository
centrale messo a disposizione da Maven, così facendo non dovremo occuparci di ricercare
ed inserire in apposite cartelle i .jar necessari alle nostre applicazioni. Per la gestione di tale
strumento, viene creato un file denominato pom.xml, dove all’interno sono definite tutte le
dipendenze con rispettivi nomi e versioni. Per la modifica del file è possibile utilizzare una
maschera grafica (form-based) la quale si apre automaticamente una volta cliccato sul file.
All’interno del pom non vengono definite solo le dipendenze, ma è possibile assegnare un
nome all’applicazione, la versione attuale e molto altro.
Di seguito uno screen-shot contenente una parte delle funzionalità disponibili una volta creato
un progetto con Maven:
Inoltre Maven mette a disposizione una serie di Archetipi già esistenti che permettono la
creazione di strutture scheletro ben definite che rispettano pattern architetturali, a seconda del
progetto da creare. E’ possibile inoltre una volta preso dimestichezza con il mezzo, difinire dei
propri archetipi per progetti futuri.
Una volta integrati Eclipse e Maven tra loro rimangono i framework GWT, Spring e Hibernate.
Sfruttiamo ora la funzionalità di Maven riguardante la creazione di nuovi progetti tramite l’utilizzo di
archetipi .
Creiamo un nuovo progetto con Maven, come archetipo scegliamo gwt-maven-plugin creato
dalla org.codehaus.mojo. In questo modo maven crea la struttura necessaria per la gestione
di un’applicazione GWT e nel file pom.xml inserisce le dipendenze necessarie per l’utilizzo del
framework.
frammento dic codice file pom.xml
[...]
<!-- GWT dependencies (from central repo) -->
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<version>${gwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>${gwt.version}</version>
<scope>provided</scope>
</dependency>
[...]
Come indicato nella sezione del capitolo 4 “La comunicazione RPC con il server” la struttura di ogni
servizio deve seguire un determinato pattern:
1. Una Classe interfaccia <NomeServizio> che estende la classe RemoteService
2. Una Classe interfaccia <NomeServizioAsync>
3. Una Classe <NomeServizioImpl> che estende la RemoteServiceServlet, la quale implementa la
logica del servizio
L’utilizzo di Maven per il processo di compilazione, permette la possibilità di autocreare il codice
della classe interfaccia asincrona <NomeServizioAsync> durante la compilazione.. Questa
funzionalità può essere individuata all’interno del file pom del progetto:
<<plugins>
- <plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.2</version>
- <executions>
- <execution>
- <goals>
<goal>compile</goal>
<goal>generateAsync</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
- <configuration>
<runTarget>com.provamaven.app.Application/Application.html</runTarget>
</configuration>
</plugin>
Nell’ IDE Eclipse all’interno della classe che utilizzerà il servizio implementato, verrà presentato
un errore dovuto alla mancanza di tale classe. Ciò non toglie il corretto funzionameto
dell’applicazione dopo la compilazione. E’ possibile disabilitare questa opzione, sarà necessario
poi scrivere l’interfaccia asincrona.
Il passo successivo è l’integrazione con Spring e Hibernate, questa volta si sfrutterà la gestione
delle dipendeze di Maven per l’integrazione. Aprendo il file pom con l’editor grafico:
Sotto la voce overview è possibile definire delle properties, così da semplificare il processo di
aggiornamento a nuove versioni degli strumenti. Si definisce quindi il nome della proprietà e il
corrispondente numero di versione. Per integrare Spring e Hibernate definiamo anticipatamente le
proprietà corrispondenti ai due strumenti:
- Creare una proprietà nominata org.springframework.version con valore 3.0.1.RELEASE
- Creare una proprietà nominata org.hibernate.version con valore 3.5.1-Final
Una volta definite le proprietà sotto la voce Dependencies è necessario inserire le dipendenze,
quest’ultime possono essere inserite effettuando una ricerca dal repository centrale tramite il tasto
Add, Oppure creandole con il tasto Create. Per definire una dipendenza è necessario riempire i
campi GroupId, Artifact Id e Version nella form Dependency Details
Dipendenze da definire:
Una volta eseguite tutte le modificare cliccare sul tasto salva ed attendere. Maven si occuperà di
effettuare il download delle dipendenze indicate dai repository e le inserirà all’interno delle proprie
librerie, rendendole disponibili a tutta l’applicazione. Viene creata una cartella locale, solitamente
situata sotto {user_home}/.m2 dove vengono scaricate le librerie indicate. Per completare
l’integrazione tra GWT e Spring è necessario effettuare il download separato di una libreria che
lavorerà da punto di collegamento tra le servlet Spring e le chiamate Rpc di Gwt. Quest’operazione
risulta indispensabile poichè la libreria non è diponibile nei repository pubblici utilizzati da Maven.
La libreria in questione è la spring4gwt reperibile all’indirizzo:
- http://code.google.com/p/spring4gwt/
Una volta effettuato il download è necessario creare una cartella denominata „lib“ sotto il path /src/
main/webapp/WEB-INF e posizionare il file „spring4gwt-0.0.1.jar“ all’interno. La stessa procedura
dovrà essere utilizzata nel caso di utilizzo di librerie personali o comunque non presenti nel
repository centrale.
Il file web.xml
Dopo aver effettuato l’integrazione tra le diverse tecnologie, il passo successivo è la configurazione
dei vari componenti all’avvio dell’applicazione. Il progetto creato tramite l’archetipo GWT crea
una vera e propria applicazione J2EE. Il file web.xml1 è il file di configurazione delle applicazioni
enterprise, nel nostro caso dovremo inserire alcuni parametri per il corretto riconoscimento e avvio
delle tecnologie usate.
In primis va indicato il file di configurazione necessario per il caricamento del contesto di Spring
applicationContext.xml (trattato più avanti). Inoltre va indicata la classe di Spring utilizzata per il
caricamento dell’application context, la org.springframework.web.context.ContextLoaderListener,
passandogli come parametro la posizione del file sopra indicato.
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>GWT-Maven-Archetype</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml </param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Successivamente viene definita la servlet di gestione per le chiamate remote effettuate da GWT
verso il server,che viene lanciata e associata alla nostra applicazione al momento dell'avvio
del web container. A questo punto entra in gioco la libreria spring4gwt tramite la classe
org.spring4gwt.server.SpringGwtRemoteServiceServlet che si occupa di intercettare le chiamate
1Un deployment descriptor è un file in formato XML, denominato web.xml, che viene utilizzato per informare il server in
cui è installata un'applicazione J2EE riguardo alla configurazione dell'applicazione stessa. In esso possono essere definiti
parametri di inizializzazione, mappature dei percorsi ed in generale, tutto ciò che contiene informazioni importanti alla
corretta esecuzione dell'applicazione
GWT.
Successivamente nella servlet-mapping vengono definiti tutti gli url a cui la servlet definita sopra
dovrà intervenire ogni volta che veranno richiesti. Tramite l’utilizzo dell’asterisco verranno serviti
tutti gli url che comincieranno con <nome-applicazione>/springGwtServices/. Da specificare che
non deve esistere un corrispondente file fisico html, jps, o di qualsiasi altra estensione, per eseguire
la servlet.
Infine troviamo il file della pagina principale:
<servlet>
<servlet-name>springGwtRemoteServiceServlet</servlet-name>
<servlet-class>org.spring4gwt.server.SpringGwtRemoteServiceServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springGwtRemoteServiceServlet</servlet-name>
< url-pattern>/com.provamaven.app.applicazione.Application/springGwtServices/*</url-
pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Il file applicationContext.xml
Il file restante è l’applicationContext.xml responsabile del’inizializzazione del contesto operativo.
E’ necessario crearlo all’interno della cartella /src/main/webapp/WEB-INF.
La prima riga da analizzare è la seguente:
<context:component-scan base-package="com.provamaven.app.applicazione" />
Grazie a questa configurazione Spring eseguirà all’avvio uno scan all’interno del pacchetto indicato,
localizzando tutte le annotazioni del tipo:
● @Component
● @Repository
● @Service
e si occuperà di instanziare le classi annotate ed iniettarle nel contesto di Spring. In questo
modo non è necessario scrivere alcun tag xml per la definizione dei beans. Un esempio
pratico è la scrittura di un servizio GWT: Quando viene definita l’interfaccia del servizio e
la rispettiva implementazione lato server, viene posta l’annotazione @Service nella classe
<nomeServizio>Impl.java. In questo modo all’avvio Spring inserirà automaticamente il servizio con
l’id fornito, all’interno del suo contesto.
Per integrare Spring con Hibernate è necessario definire all’interno dell’ applicationContext
l’ EntityManager per la gestione delle persistenze. Va definito quindi il bean chiamato
entityManagerFactory tramite la classe org.springframework.orm.jpa.LocalEntityManagerFactoryBean e come
proprietà va inserito il nome del nostro assegnato all’interno del file persistence.xml (trattato più
avanti). l’entityManagerFactory si occuperà quindi di gestire il datasource.
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="MyPersistenceUnit" />
</bean>
Successivamente viene definito il transactionMenager passandogli come riferimento la factory sopra
creata, in questo modo viene creata il meccanismo per l’esecuzione delle transazioni JPA. La
classe incaricata è la org.springframework.orm.jpa.JpaTransactionManager
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<context:annotation-config/>
Al termine di questa procedura avremo tutti gli strumenti integrati tra loro e pronti all’utilizzo, nella
prossima sessione vedremo le configurazioni necessarie per la comunicazione in un database
d’esempio.
Ultimo passo: comunicazione con un database relazionale
Nel sezione precedente si sono eseguiti tutti i passi necessari per la preparazione dell’IDE di
sviluppo Eclipse. L’ultima parte riguarda invece la scelta del DataBase relazionale da utilizzare e
le configurazioni necessarie per l’utilizzo. Uno dei vantaggi nell’uso degli strumenti presentati sin
d’ora, è quello di poter variare la base dati a cui si fa riferimento con delle semplici modifiche.
Nel nostro caso utilizzeremo mySQL come DB. Grazie all’utilizzo di Hibernate come livello
intermedio tra l’applicazione creata e il DB, non saranno presenti problemi di compatibilità poichè
Hibernate stesso si occuperà di tradurre il linguaggio sql scritto nel corrispondente dialetto della
base di dati sottostante.
Connection pool
Il "Connection Pool" è come se fosse un oggetto che gestisce un insieme di connessioni, la cui
logica di funzionamento è piuttosto semplice.
Quando viene istanziato, questo gestore si occupa di aprire una serie di connessioni verso
il database. Ogni qualvolta altri oggetti necessitano di accedere al database, richiedono la
connessione al gestore che ne fornisce una libera. Quando l'operazione sarà terminata l'oggetto
restituirà la connessione al gestore che potrà quindi metterla a disposizione di altri oggetti che la
richiederanno. In questo modo non vi sarà alcun degrado nelle prestazioni, in quanto le connessioni
non saranno ricreate ogni volta, ma solamente in fase di attivazione dell'applicazione, così come
non vi saranno rischi di connessioni inattive bloccate per lungo tempo, in quanto, una volta
completata l'operazione, questa viene rilasciata ritornando nuovamente a disposizione.
Hibernate mette a disposizione la possibilità di utilizzare c3p0 come connection pool per la gestione
delle connessioni. Più avanti verrà presentato il file necessario per la configurazione.
Integrazione MySQL
Per l’inserimento delle librerie necessarie utilizzeremo ancora una volta Maven.
Nel file pom.xml, sotto la voce dependencies, cliccando sul tasto add è possibile effettuare una
ricerca diretta nel repository centrale.
La libreria da ricercare,necessaria alla comunicazione è la seguente:
● mysql-connector-java
Ad ogni DB corrisponde una specifica libreria, ad esempio se il database utilizzato fosse stato
Hipersonic:
● org.hsqldb
Dopo le prime righe di intestazione si definiscono i primi parametri di creazione per il livello delle
persistenze:
name
(Attributo) Nome dell’entity manager. Questo parametro viene utilizzato alla creazione
dell’EntityManagerFactory al boot di Spring.
transaction-type
(Attributo) tipo di transazione utilizzato. O JTA o RESOURCE_LOCAL (di default viene utilizzato JTA
in un ambiente JavaEE e RESOURCE_LOCAL in un ambiente JavaSE). Quando viene utilizzato
un JTA- datasource, di default viene settato JTA, altrimenti viene utilizzato per default il paramentro
RESOURCE_LOCAL.
provider
Va specificato il nome completo della classe che implementa il provider ejb.
org.hibernate.ejb.HibernatePersistence è il provider di Hibernate che implementa le EJB3
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/
persistence_2_0.xsd"
version="2.0">
Nella parte <properties> vengono definite tutte le proprietà riguardanti la tipologia del DB, il
dialetto utilizzato, l’indirizzo del server DB, e lo username e password per la connessione.
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost/commenti" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="" />
inoltre viene definito il connection pool necessario all’applicazione per la comunicazione, in questo
caso viene utilizzato il c3p0 e le sue voci principali settate di default sono::
min_Size e max_Size
dimensione minima e massime del pool di connessioni a seguito di aperture e chiusure successive.
timeout
tempo massimo prima che una connessione sia considerata scaduta e sia chiusa.
max_statements
abilita e disabilita la cache dei PreparedStatements
<property name="hibernate.c3p0.min_size" value="5" />
<property name="hibernate.c3p0.max_size" value="20" />
<property name="hibernate.c3p0.timeout" value="300" />
<property name="hibernate.c3p0.max_statements" value="50" />
<property name="hibernate.c3p0.idle_test_period" value="3000" />
</properties>
<persistence-unit>
</persistence>
Al termine delle configurazioni sopra indicate, la creazione di ogni servizio seguirà la seguente
struttura di interfacce.
SCHEMA COMPLETO
RIFERIMENTI:
http://community.jboss.org/wiki/HowToconfiguretheC3P0connectionpool
http://www.mchange.com/projects/c3p0/index.html#appendix_d