Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
OPPURE
inviaci il coupon
Linux - La Guida sottostante Internet Phone Services
(con DVD) Simplified (VoIP)
di J. Davies et al.
al numero di fax di J. Doherty e N.
copertina
non
0587/732232 Anderson
OPPURE
Addison Wesley
del 20% se acquisti Sams
568 pp, euro 60.70
ISBN 0321269667
3 libri 456 pp, euro 45.50
ISBN 067232704X
JAVA JOURNAL 1
www.infomedia.it EDITORIALE
JAVA Journal
Java Journal
BIMESTRALE - ANNO 1 - N.1
DIRETTORE RESPONSABILE
numero 1
MARIALETIZIA MARI
(MMARI@INFOMEDIA.IT)
DIRETTORE ESECUTIVO
MICHELE SCABARRÀ
(MICHELE.SCIABARRA@JAVAJOURNAL.IT)
EDITORIAL BOARD Mentre scrivo queste righe ho in mano il numero della rivista Computer Programming
UGO LANDINI, STEFANO SANNA, del 1996 con lo speciale su Java, in cui scrissi due articoli cercando di spiegare cosa
TO N Y M O B I L Y era Java e come si facevano le applet. Era una delle mie primissime esperienze di
autore tecnico, quindi rivivo la cosa con emozione e nostalgia.
COLLABORATORI Java era allora alla versione 1.0; ciò nonostante la sua inclusione nel nuovissimo
Netscape 2.0,(qualcuno si ricorda che era il web browser leader di mercato?), ave-
MATTEO CAMPANELLA va fatto scalpore, creato fermento ed eccitazione, e scatenato un effetto domino di
UGO LANDINI dichiarazioni di supporto della tecnologia. Si erano dichiarati “amici di Java” nomi
ANDREA NASATO come IBM, Oracle e perfino Microsoft.
STEFANO SANNA Sono passati più di dieci anni (non mi sembra vero, ma è così), e tanto è cambiato.
FA B I O S T A R O Per esempio, di applet, la tecnologia allora rivoluzionaria, quasi non si parla più (le
ANDREA ZITO applet sono rimaste una applicazione di Java tutto sommato di nicchia).
Java comunque ha superato i confini del Browser, si è installato stabilmente nei
Server, ed è diventato uno dei linguaggi di programmazione più usati al mondo. Pur
non essendo (ancora) un linguaggio strettamente Open Source (nel senso di licenza
OSI-compatibile), di fatto il suo modello di sviluppo si è sempre avvicinato molto a
quello dell’Open Source. Una enorme quantità di ambienti e strumenti di sviluppo
per Java sono Open Source. Recentemente Java è diventato il linguaggio più usato
nei progetti del repository di SourceForge, il più grande sito che fornisce risorse per
lo sviluppo open. Sul lavoro, vengo consultato come esperto di “Java in ambiente
GRUPPO EDITORIALE INFOMEDIA SRL Open Source”. Quindi, anche se qualche purista potrà storcere il naso, Java viene
V I A V A L D E R A P. 1 1 6 associato comunemente all’Open Source.
5 6 0 3 8 PO N S A C C O ( P I ) I T A L I A Ricordo che Java ha in gran parte sostituito il Pascal nelle università come linguaggio
TE L 0 5 8 7 7 3 6 4 6 0 F A X 0 5 8 7 7 3 2 2 3 2 didattico; questo per due motivi: il primo è che è pulito e chiaro come il Pascal, ma
E-MAIL INFO@INFOMEDIA.IT rispetto a quest’ultimo è anche Object Oriented; il secondo è che si tratta di un lin-
S I T O W E B W W W. I N F O M E D I A . I T guaggio effettivamente molto usato in pratica. La maggior parte dei programmatori
quindi, anche se lavora con altri linguaggi, generalmente ha qualche interesse verso
Java, se non altro per completezza professionale.
DIREZIONE Nel frattempo, l’altro grande figlio di Internet, Linux, il sistema operativo vessillo
N A T A L E FI N O (NFINO@INFOMEDIA.IT) dell’Open Source (e del Free Software, per chi è interessato alla differenza) ha an-
ch’esso guadagnato molto terreno. Notare che è anche diventato un fenomeno edi-
CONTATTI toriale qualche anno fa. In Italia sono comparse numerose riviste dedicate a Linux.
Mi aspettavo quindi da un momento all’altro una rivista dedicata a Java. Infatti la
TE C H N I C A L B O O K quantità di programmatori Java, o aspiranti tali, è di tutto rispetto.
(BOOK@INFOMEDIA.IT)
Infatti, nonostante l’uso di Internet per trovare informazioni, la rispettabilità, la pia-
cevolezza e la qualità di una buona rivista non sono mai venute meno rispetto alla
MARKETING & ADVERTISING ricerca sul Web. La storia insegna che un nuovo media non sostituisce mai un altro,
SEGRETERIA: 0587736460 semmai lo affianca.
MARKETING@INFOMEDIA.IT Purtroppo, per anni, in Italia non ho trovato niente. Abbiamo una quantità impres-
sionante di riviste dedicate ai telefonini, ma nessuna rivista dedicata a Java. Eppure
AMMINISTRAZIONE in altri paesi di riviste Java ce ne sono parecchie; conosco moltissimi programmatori
(AMMINISTRAZIONE@INFOMEDIA.IT)
Java regolarmente abbonati alle riviste estere.
SEGRETERIA Così, quando in una chat session con Tony Mobily, mi lamentavo di questa mancan-
(INFO@INFOMEDIA.IT) za, sono rimasto gelato dalla proposta: “perché non la fai tu”? A breve, mi ha messo
in contatto con Marialetizia Mari, direttore responsabile delle riviste del Gruppo
GRAFICA Editoriale Infomedia, che mi ha confermato l’interesse.
(GRAFICA@GRUPPOINFOMEDIA.IT)
Siccome non è corretto lamentarsi di una mancanza per poi tirarsi indietro quando
è il momento di rimediare, mi sono messo al lavoro. Dopo un rapido giro di email...
ho quasi riempito il primo numero! Ho trovato tanto entusiasmo e disponibilità. Non
UFFICIO ABBONAMENTI ci credevo! I commenti praticamente unanimi sono stati: “bella idea”, “ci vuole”,
TE L 0 5 8 7 7 3 6 4 6 0 F A X 0 5 8 7 7 3 2 2 3 2 “collaboro anche io”.
ABBONAMENTI@INFOMEDIA.IT Prima di completare il lavoro sono passati mesi, ma eccoci qui: la prima rivista in
W W W. I N F O M E D I A . I T italiano dedicata a Java è appena nata. Spero vi piaccia e sia utile per lavoro o per
studio. Confidiamo nel vostro sostegno concreto, diventando abbonati, ma anche
JAVA E TUTTI I MARCHI DERIVATI proponendo commenti, critiche e facendola conoscere ad amici e colleghi che, come
SONO MARCHI O MARCHI REGISTRATI
voi, cercavano una rivista italiana su Java. Fateci sapere cosa ne pensate scrivendo a
michele.sciabarra@javajournal.it.
DI SUN MICROSYSTEMS, INC. NEGLI
U S A E I N A L T R I PA E S I . I L G R U P P O Michele Sciabarrà
EDITORIALE INFOMEDIA È INDIPEN- Direttore Esecutivo
DENTE DA SUN MICROSYSTEMS, INC. Java Journal
Speciale JSF
Primi passi con JavaServer Faces
di Michele Sciabarrà 10
Le novità di JSF 1.2
di Andrea Nasato 17
Un Wizard per il Web con JSF e Shale
di Fabio Staro 23
Focus
JavaCard
di Matteo Campanella 30
Gcj: Gnu Compiler for Java
di Andrea Zito 36
Java ME sviluppare applicazioni per cellulari e PDA
di Stefano Sanna 42
Educational
Java 5, le buone nuove e le novità meno buone
di Ugo Landini 49
Fondamenti di Programmazione Java
Prima parte: uno sguardo d’insieme
di Michele Sciabarrà 55
Rubriche
Idiomatica
Codice orribile, antipattern e pratiche discutibili
di Ugo Landini 62
Community
Intervista a Daniela Ruggeri, presidente della
Java Italian Association
di Michele Sciabarrà 64
L
e JavaServer Faces sono state proget- JSF sono in realtà delle pagine JSP che contengo-
tate per ridurre il codice da scrivere no dei tag provenienti dalla libreria Faces. Tutta-
quando una applicazione Web ha nu- via, una pagina in JSF deve essere chiamata con
merose form; quasi sempre si tratta di l’estensione.faces (non .jsp) o con il prefisso /faces/;
una interfaccia a dati memorizzati su su disco però vengono memorizzate con la clas-
un database relazionale. In una appli- sica estensione .jsp. Dove è l’inghippo? Semplice:
cazione Web in Java “tradizionale”, quando installiamo le JSF, dobbiamo configurare
ci sono delle JavaServer Pages o delle servlet che nell’applicazione Web una “servlet”, la faces servlet
producono esplicitamente tutto l’html necessario che interpreta le pagine JSF. Questa servlet prepara
per visualizzare le form. Per gestire le form il pro- l’ambiente perché una JSF possa essere eseguita. In
grammatore Web finora doveva fare da solo. Una effetti è un sistema un po’ strano, non ovvio; pur-
applicazione Web infatti richiede una serie di auto- troppo questo “trucco” è necessario perché si possa
matismi che con le sole JSP non possiede: è neces- mantenere la compatibilità con molti application
sario riempire le form con dei dati, mantenere uno server esistenti.
stato, raccogliere e decodificare i dati, spesso codi- Oltre alle pagine JSF avremo delle classi, che sono
ficarli o decodificarli, e infine salvarli in un data- necessarie per usare le JSF. A differenza delle JSP
base. Per quanto riguarda la gestione del database, infatti, le JSF prevedono che molte operazioni delle
questo è compito di librerie ORM (Object Relatio- JSF, vengano svolte in delle classi apposite, dette
nal Mapping), e non verrà considerato nel presen- “Backing Bean”.
te articolo.
Le JavaServer Faces hanno l’obiettivo principale di
aumentare l’automatismo per riempire le form con
i dati, recuperarli quando l’utente li inserisce, e in
generale gestire l’interazione con l’utente. Vedremo
Le
pagine JSF sono
come fare costruendo un esempio pratico passo pas-
so. Si tratterà di un esempio molto semplice, ridotto pagine JSP che conten-
all’osso, che visualizza un elenco dati e permette di
modificarlo. La memorizzazione dei dati verrà gesti- gono tag provenienti
ta con uno “stub”, una classe minimale (da esten-
dere eventualmente) perché altrimenti andremmo dalla libreria Faces
fuori dallo scopo dell’esempio.
Personaggi e Interpreti
Installazione di JSF
Agenda(“nome”, “email”, “telefono”). Per salvarlo useremo due maschere: una maschera principale che elenca tutti
Agenda.store(a), mentre per recuperarlo (assumendo di i record, e una seconda maschera di dettaglio, che per-
avere già l’id) basterà un Agenda.load(id). Infine, per eli- mette di modificare il singolo record. Entrambe fanno
minarlo possiamo utilizzare Agenda.delete(a). Il codice del riferimento a un unico backing bean, agenda. Iniziamo a
“database” segue in Listato 3. vedere il codice della lista, in Listato 4:
Nel Listato 4 possiamo vedere come si fa a ottenere un
La lista e la form elenco di record del database, come è visualizzato nella
Figura 2. Si può notare che JSF usa dei tag, con prefisso
La nostra applicazione è composta essenzialmente di f: oppure h:, descritti in dettaglio nell’articolo successivo.
Il backing bean
<%@ taglib uri=”http://java.sun.com/jsf/html” prefix=”h”%>
<%@ taglib uri=”http://java.sun.com/jsf/core” prefix=”f”%> È venuto il momento di chiudere il cerchio, ri-
<f:view> portando il codice del backing bean mostrato nel
<h:form> Listato 6. Potrebbe sembrare strano che il codice
<h:panelGrid columns=”3”> sia così semplice, però è proprio così. Tutti i meto-
<h:outputLabel value=”Nome:” for=”nome” /> di sono di una sola riga, e molti metodi possono
<h:inputText id=”nome” value=”#{agenda.nome}” /> essere scritti in maniera automatica sfruttando
<h:message for=”nome” /> gli automatismi forniti dagli IDE: per esempio per
scrivere i getter/setter o i proxy.
<h:outputLabel value=”Email:” for=”email” /> Per capire come funziona il tutto, vediamo cosa
<h:inputText id=”email” value=”#{agenda.email}” /> succede nei dettagli, avendo il codice sott’occhio e
<h:message for=”email” /> tenendo presente quanto abbiamo visto nei para-
grafi precedenti.
<h:outputLabel value=”Phone:” for=”phone” /> Innanzitutto l’utente chiama la pagina
<h:inputText id=”phone” value=”#{agenda.phone}” /> AgendaList.jsp che abbiamo visto nel Listato 3.
<h:message for=”phone” /> Per visualizzare l’elenco dei metodi la JSF chiama
AgendaBacking.getList(). Il backing bean produce la
</h:panelGrid> lista dei bean prendendoli dal database, con il me-
<h:commandButton value=”Salva” todo statico Agenda.getList(). I vari bean vengono
actionListener=”#{agenda.save}” action=”list”/> posti nella variabile data e i dati correnti vengono
</h:form> visualizzati. I vari #{data.name} chiamano il me-
</f:view> todo getName della classe Agenda. La datatable ac-
cede direttamente ai bean che contengono i dati.
A questo punto un utente decide di modificare
LISTATO 5 Il dettaglio dell’agenda
un bean, e preme il bottone Modifica. La form vie-
Le novità di
JSF 1.2
La tecnologia JSF (Java Server Faces) continua il suo processo di maturazione. Dopo la versio-
ne 1.1 che mirava a dare stabilità alle specifiche, la nuova versione di JSF diventa una tecnologia
centrale della piattaforma JEE5. Ad agosto del 2005 infatti sono state pubblicate le specifiche per
la versione 1.2, attualmente ancora in stato di “Proposed Final Draft”. In questo articolo vedremo
quali sono le novità e a quali problemi è stato posto rimedio.
L
versione: dalla 1.1 alla 1.2.
JSP, a partire dalla versione 2.0, era già dotato di un
a nuova versione delle specifiche expression language, derivato da quello presente nel-
di JSF si pone essenzialmente due le JSTL 1.0. L’EL di JSP ha però due importanti limi-
obiettivi. Il primo è quello di inse- tazioni: la valutazione dell’espressione è immediata
rire in maniera più marcata il fra- ed è in sola lettura.
mework all’interno dell’architettu- La valutazione immediata è quella che avviene nel
ra JEE. Infatti anche altre tecnolo- momento in cui il motore JSP compie il render del-
gie, già presenti in JEE, hanno su- la pagina. L’analisi avviene scandendo il sorgente
bito dei cambiamenti e la loro relazione con JSF partendo dall’alto verso il basso. Quando viene in-
si è fatta più stretta. Inoltre dalla versione JEE5 contrato un token dell’EL, questo viene immediata-
troveremo JSF come componente fondamenta- mente valutato e ne viene fatto il bind con l’oggetto
le: ogni vendor che vuole ottenere la certificazio- referenziato. Questo tipo di espressione (della forma
ne Sun dovrà fornire una implementazione della ${expr}) può essere usata da sola all’interno della
specifica. pagina, oppure come valore di un tag JSP che accetta
Il secondo obiettivo è di porre rimedio ai problemi espressioni valutate a run time.
riscontrati dagli sviluppatori che hanno utilizzato la
tecnologia. Si va dalla semplice correzione di bug,
all’adeguamento delle specifiche a tecnologie ormai
consolidate in internet come AJAX. Nell’articolo ci
concentreremo su entrambi questi aspetti tentando
Novità importante è
di capire quali sono state le motivazioni che hanno
guidato l’expert group. l’introduzione di
Unified Expression Language
Unified Expression
La prima importante novità è l’introduzione dell’Uni- Language (EL)
fied Expression Language (EL). In realtà questa non
è una vera e propria novità di JSF; il fatto nuovo è che
l’EL usato in JSF diverrà comune anche a JSP (Java
Server Pages) e a JSTL (Java Standard Tag Library). Deferred Evaluation
Ciò ha comportato una revisione delle specifiche an- Si pone il seguente problema: in JSP una volta che il
che per queste due tecnologie. bind a una variabile è stato fatto, non è più possibile
L’expression language che caratterizza JSF, a partire modificarlo, ovvero l’EL di JSP non ha il concetto di
dalla versione 2.1 di JSP, viene “spostato” da JSF a fase che invece è proprio di JSF. Inoltre i token dell’EL
JSP. Ciò comporta che tutto il package javax.faces.el.* JSP sono read-only. Dato ad esempio un bean, di que-
di JSF viene deprecato e tutte le sue classi e metodi sto si può solo fare il get delle proprietà e non il set.L’EL
vengono replicati nel package javax.el.* che sarà con- di JSF invece non presenta questi problemi: permette
tenuto in JSP. Anche JSTL si adeguerà al nuovo EL infatti quello che si chiama deferred evaluation.
Per deferred evaluation si intende che il JSP engine viene sol- di restore view (attraverso il nuovo metodo isPostBack() di
levato dal compito di valutare l’espressione, compito che ResponseStateManager) si accorge che ora è un evento di
viene invece affidato a fasi successive del ciclo di vita. La postback, e fa procedere il ciclo di vita. In particolare i due
forma (precisamente #{expr}) di un’espressione di questo valori verrano usati in queste fasi:
tipo è quella abituale all’interno dei tag JSF che si riferi-
scono a proprietà e metodi pubblici di un managed bean. • process validation: il framework controlla la correttezza
Vediamo un esempio di funzionamento di questo meccani- formale dei parametri forniti dall’utente;
smo nel Listato 1. • update model values: nel caso in cui la fase di validazione
sia superata con successo, i due valori servono ad aggior-
L’esempio propone una semplice pagina di login, in nare il nostro bean user;
cui sono presenti i classici due campi di input. Sup-
poniamo che un utente apra una sessione del browser
e richieda la pagina. Quando arriva una tale richiesta,
JSF entra nella fase di restore view. Durante questa fase
il framework si accorge che è la prima richiesta della
pagina, quindi cortocircuita il resto delle fasi e passa il
Per deferred evalua-
testimone direttamente alla fase di render response (vedi tion si intende che il JSP
Figura 1). Tale fase valuta l’espressione #{user.login}
proprio come se fosse una valutazione immediata. In
engine viene sollevato
questo caso all’utente viene proposta la pagina con i due dal compito di valutare
campi di input vuoti.
l’eccezione
Quando invece arriva la seconda richiesta (cioè l’utente
ha digitato login e password e ha premuto invia), la fase
<web-app>
JSF fornisce di default il render kit per l’HTML, ma per-
<jsp-property-group>
mette di aggiungere modalità di presentazione anche per
<deferred-syntax-allowed-as-literal>
client che interpretano altri meta linguaggi. È ad esem-
true
pio possibile creare un render kit che genera codice SVG
</deferred-syntax-allowed-as-literal>
</jsp-property-group>
(Scalable Vector Grafix) oppure XUL (Xml User Interface
... Language), usato da Firefox, o addirittura Flex.
</web-app> Questa caratteristica esiste sin dalla prima versione delle
specifiche; ciò che non si poteva fare fino ad ora era uti-
LISTATO 3 deployment descriptor lizzare render kit differenti all’interno della stessa web ap-
plication: ad esempio non si poteva passare da una pagina
in HTML a una in SVG ad una in XUL, mantenendo come
Unified Expression Language e JSTL model e controller JSF. O meglio questo si poteva fare, ma
si doveva definire un ViewHandler custom che fosse in gra-
Lo unified expression language viene esteso anche a JSTL. do di gestire i vari render kit.
Infatti anche i tag JSTL possono contenere delle espres- Adesso è sufficiente definire in pagina quale sia il render
sioni da valutare a run time e come accade nel caso pre- kit da usare, specificandolo nell’attributo renderKitId del
cedente, tali espressioni vengono valutate dal motore JSP tag f:view e avendo l’accortezza di definire nel file faces-
ogniqualvolta la pagina viene interpretata. config.xml il tag render-kit-id con lo stesso valore.
Consideriamo l’esempio del Listato 2, in cui si compie un
ciclo sui valori di un bean attraverso il tag JSTL forEach e
si presenta ogni valore attraverso il tag JSF outputText. A
causa dei diversi momenti in cui le espressioni vengono
valutate, il codice non si comporta come ci aspettiamo.
JSF astrae il mecca-
Con la nuova versione di JSTL che si appoggerà all’ex-
pression language definito in JSP, il codice del Listato nismo di presentazione
3 funzionerà correttamente a patto di cambiare $ con #
nell’attributo items del tag forEach. al client definendo
il render kit
Unified Expression Language – Alcuni problemi di
compatibilità
La modifica delle specifiche JSP comporta alcuni problemi Nuovo Tree Creation e Content Interweaving Model
di compatibilità con il codice scritto fino alla versione 2.0.
Infatti fino a tale versione la coppia di caratteri #{ non Nelle applicazioni con JSF la vista viene spesso realizzata
rappresentava una parola riservata. Era quindi perfet- come una pagina JSP all’interno della quale trovano posto
tamente lecito usare tale combinazione all’interno della i componenti JSF. Fino alla versione 1.1 del framework la
pagina JSP. convivenza tra scriptlet JSP e tag JSF non era gestita al
Supponendo di avere realizzato una web application che meglio.
usava i caratteri #{ all’interno delle pagine e volendo farne Si prenda in considerazione il Listato 4 che rappresenta
un deploy su un container che supporta le specifiche JSP una pagina JSP contenente un tag JSF che raggruppa due
2.1 ,si presentano 3 alternative: elementi, un tag JSF che stampa un messaggio e, di segui-
• procedere all’escape dei caratteri all’interno delle pagine to, uno scriptlet JSP che stampa un secondo messaggio.
JSP, ovvero usare l’espressione \#{; Visualizzando la pagina attraverso un browser ci si attende
• inserire nel deployment descriptor (l’usuale file web.xml) di vedere, in sequenza, “Messaggio 1” e “Messaggio 2”.
il codice di Listato 3;
• usare in pagina la direttiva <%@page … deferredSyntaxAll Ciò che avviene invece è proprio il contrario: viene prima
owedAsLiteral=”true” %> visualizzato “Messaggio 2” e poi “Messaggio 1”.
Utilizzando uno di questi accorgimenti l’applicazione potrà Il motivo di questo comportamento è il seguente. Il mo-
funzionare anche con la nuova specifica.
1:<%@ taglib uri=”http://java.sun.com/jsf/html”
prefix=”h”%>
2:<%@ taglib uri=”http://java.sun.com/jsf/core”
Render Kit
prefix=”f”%>
Un’altra novità importante riguarda i render kit. Come 3:<f:view>
noto JSF è un framework nato per la presentazione di 4: <h:panelGroup>
contenuti sul web, quindi è naturale pensare che l’output 5: <h:outputText value=”Messaggio 1” />
inviato al client sia HTML. In realtà JSF astrae il mecca- 6: Messaggio 2
nismo di presentazione al client definendo il render kit, 7: </h:panelGroup>
che è quell’insieme di classi aventi il compito di definire la 8:</f:view>
modalità di presentazione.
LISTATO 4 il problema del content interweaving
tore JSP analizza la pagina dall’alto verso il basso fino fasi è l’istanza di UIViewRoot, che viene creato nella prima
ad incontrare il tag h:panelGroup. I figli di questo tag (h: fase (la restore view), che per questo motivo è l’unica nella
outputText in questo caso) demandano il render di sé stessi quale non ci sono eventi.
al padre. Quindi il render di outputText non avviene finché Questo meccanismo risulta comodo nel caso in cui si
non si raggiunge la chiusura del tag panelGroup. A questa vogliano gestire le richieste AJAX. Si supponga infatti di
regola non sono però soggetti gli scriptlet JSP, quindi appe- creare un AjaxPhaseListener il quale avrà il compito di capi-
na trova “Messaggio 2” il motore JSP ne compie il render. re, una volta ricevuta la notifica, se questa è stata generata
Questo errato comportamento è noto come “content inte- da una richiesta AJAX.
rweaving problem”. Se questo è il caso, il listener potrà attivare la logica che
Per ovviare a questo inconveniente sono stati apportati soddisfa la richiesta e cortocircuitare il resto delle fasi chia-
numerosi cambiamenti strutturali. La seguente descrizio- mando il metodo renderResponse() o responseComplete().
ne non è semplice, chi non è interessato può passare al In questo modo la richiesta AJAX, non dovendo passare per
prossimo paragrafo. tutte le fasi del ciclo di vita, viene servita più velocemente.
Sono stati cambiati la specifica di realizzazione del
ViewHandler delle pagine JSP e la classe che rappresenta il LifeCycle diversi all’interno della stessa applicazione
custom tag JSP usata da tutti i componenti JSF. L’enco- Un’altra novità è la possibilità di definire, all’interno del-
ding non viene più fatto mentre la pagina JSP viene ana- la stessa applicazione, più istanze della servlet FacesServlet
lizzata, durante questa fase viene unicamente costruito con URI mapping diversi. Ad ognuna di queste istanze è
l’albero dei componenti e solo quando questo è completo possibile associare un ciclo di vita diverso. Il meccanismo
(l’albero comprende anche i componenti non JSF) si pro- di associazione prevede che nel metodo init della servlet
cede all’encoding. In questo modo l’autore delle pagine avvenga l’acquisizione dei riferimenti alle particolari
non si troverà più a dover fronteggiare strani comporta- istanze di Lifecycle e FacesContextFactory da usare nella web
menti come quello descritto nell’esempio 5. application.
Utilizzando il parametro javax.faces.LIFECYCLE_ID, che
può essere specificato come init-param della servlet oppure
come context-param della web application, si può specifica-
Due
re l’implementazione del ciclo di vita da usare.
nuovo concetti Questo meccanismo permette di creare un ciclo di vita
specifico per soddisfare le richieste AJAX (ad esempio con
un numero minore di fasi) e di associarlo ad una istanza
si prestano bene ad un di servlet dedicata.
Un Wizard per
il Web con
JSF e Shale
Le applicazioni web presentano, in talune circostanze, elaborazioni in stile wizard. Con Java Server
Faces e Shale è possibile realizzare wizard per il web in modo funzionale, chiaro ed elegante.
L
le ed infine il quarto passo chiede una conferma per
i dati inseriti. Osserviamo come in ciascun passo sia
’uso di wizard, anche noti come crea- possibile tornare indietro e modificare i valori prece-
zioni guidate, è comune in molte atti- dentemente inseriti.
vità svolte davanti al computer: dalla
creazione di documenti alla installa- La realizzazione del semplice wizard proposto si basa
zione di application server o databa- su quattro pagine JSP. La pagina “anagrafica.jsp”
se. Tecnicamente un wizard è una se- raccoglie i dati anagrafici di un utente, la pagina
quenza di schermate atte a raccogliere “istruzione.jsp” i dati relativi alla formazione uni-
le informazioni necessarie nella realizzazione di uno versitaria, la pagina “esperienzeLavorative.jsp” i dati
specifico compito. I wizard rendono l’interazione con relativi alle esperienze lavorative ed infine la pagina
gli utenti maggiormente comprensibile, suddividen- “confermaDati.jsp” chiede conferma all’utente dei
do la richiesta di informazione in blocchi logici, evi- dati inseriti. La navigazione tra le pagine è definita
tando, pertanto, la proposizione di una unica, com- nel file faces-config.xml di cui ne riportiamo uno stral-
plessa ed eccessivamente lunga schermata. cio ed in Figura 2 ne diamo una rappresentazione
In questo articolo realizzeremo un wizard per il web grafica:
con JavaServer Faces (JSF) mostrando come sia van-
taggioso realizzarlo attraverso il supporto alla “gestio- …
ne dei dialoghi” offerto dal framework Shale basato su <navigation-rule>
JSF. L’articolo non è una introduzione a JSF, dandone <from-view-id>/anagrafica.jsp</from-view-id>
per acquisita una conoscenza di base, mentre intro- <navigation-case>
duce Shale e le sue features. <from-outcome>success</from-outcome>
Il framework Shale è uno dei progetti della Apache <to-view-id>/istruzione.jsp</to-view-id>
Foundation, collegato al progetto Struts, che ha come </navigation-case>
obiettivo estendere JSF per fornire nuove funzionali- </navigation-rule>
tà che semplificano lo sviluppo. <navigation-rule>
<from-view-id>/istruzione.jsp</from-view-id>
<navigation-case>
<from-outcome>indietro</from-outcome>
Un semplice wizard
<to-view-id>/anagrafica.jsp</to-view-id>
Il wizard che vogliamo realizzare, volutamente </navigation-case>
semplice al fine di soffermarci sugli aspetti tecnici <navigation-case>
e non funzionali, prevede quattro passi, illustrati <from-outcome>success</from-outcome>
nella Figura 1, per la raccolta delle informazioni <to-view-id>/esperienzeLavorative.jsp
anagrafiche e professionali di un utente: il primo </to-view-id>
passo consente l’inserimento dei dati anagrafici del- </navigation-case>
l’utente, il secondo l’inserimento delle informazioni </navigation-rule>
relative al percorso formativo, il terzo passo permette <navigation-rule>
<from-view-id>/esperienzeLavorative.jsp
</from-view-id>
<navigation-case>
<from-outcome>indietro</from-outcome>
<to-view-id>/istruzione.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/confermaDati.jsp
</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/confermaDati.jsp</from-view-id>
<navigation-case>
<from-outcome>indietro</from-outcome>
<to-view-id>/esperienzeLavorative.jsp
FIGURA 2 Rappresentazione grafica, ottenuta
con il tool di sviluppo Oracle JDeveloper 10g, della
</to-view-id>
navigazione tra le quattro pagine JSP del wizard
</navigation-case>
</navigation-rule> conto solo di “cosa succede” piuttosto che domandarsi “dove
… devo andare ora”. Questo concetto è presente nella maggior
parte dei framework web basati sul paradigma Model
Osservando le righe di codice riportate possiamo nota- View Controller (MVC) che adottano il design pattern
re come “nativamente” il framework JavaServer Faces front-controller. Per esempio il framework Struts 1.x, proba-
supporti un meccanismo che permette di definire, in un bilmente il più diffuso framework web, presenta il metodo
file XML di configurazione, le regole di navigazione tra le Action.execute() che ritorna un oggetto di tipo ActionForward
varie pagine costituenti una applicazione. In particolare, il quale descrive il valore logico di “outcome”. Tuttavia
l’algoritmo che definisce la navigazione tra le pagine è per quanto analizzato finora dobbiamo notare come il
definito in JSF dall’implementazione della classe astratta framework JavaServer Faces, analogamente al framework
javax.faces.application.NavigationHandler. L’implementazione Struts 1.x, permetta una elaborazione in stile wizard ma
standard fornita dal framework determina la navigazione al prezzo di legare nel codice e nel file di configurazione
da una pagina ad un’altra in base a a tre dati di input: faces-config.xml i passi del workflow, riducendo di fatto la
possibilità di riutilizzare i singoli passi di cui è composto
• Quale pagina sta correntemente processando il form; il flusso e soprattutto non isolando chiaramente i flussi
• Quale azione, tra quelle potenzialmente possibili, è stata stessi (per esempio il wizard presentato non termina con
invocata; la pagina “confermaDati.jsp” ma con la successiva azione
• Quale è il valore ritornato dall’azione invocata; di business invocata sull’onclick() del pulsante “Avanti”).
In particolare ogni pagina JSP deve sapere esplicitamen-
Il meccanismo di navigazione offerto dal framework JSF, te quale è l’azione da invocare per proseguire nel passo
basato sul valore logico, “logical outcome”, restituito dagli successivo del wizard. Il seguente frammento di codice,
action method presenti nei backing managed bean, riduce estratto dalla pagina JSP anagrafica.jsp, chiarisce quanto
l’accoppiamento tra le pagine poiché quando si realizza un espresso:
action method lo sviluppatore del backing bean deve tener
<h:commandButton value=”Avanti” action=”#{anagrafica.insert
Anagrafica}”/>
Introduzione a Shale
FIGURA 1 I passi del wizard Con il framework Shale estendiamo le JavaServer Faces.
Infatti il framework JSF versione 1.1 segnala la carenza di identificato. L’implementazione di default in JSF della
alcuni servizi tra i quali: classe VariableResolver ricerca un oggetto, identificato dalla
• un sistema evoluto per la gestione del layout delle pagine chiave specificata, nei diversi “scope” dell’applicazione (re-
web; quest, session o application). Supponiamo ora di estendere il
• un sistema di gestione per la navigazione tra le pagine comportamento standard di JSF in modo tale che sia pos-
web in stile wizard; sibile ricavare attraverso una espressione JSF EL anche il
• una migliore interazione con i managed bean durante valore di variabili definite nel file di deployment descriptor,
le fasi costituenti il ciclo di vita di una richiesta di tipo ossia il web.xml, di una web application (l’esempio è voluto
faces. essendo questa una semplice feature di Shale che tuttavia
• la presenza di validatori client-side; chiarisce il modo di interagire con le classi pluggable). Per
• il supporto per il remoting (AJAX [2]); ottenere questo risultato le classi di default da estendere
sono proprio VariableResolver e PropertyResolver. Decorando
Tuttavia JSF è un framework estremamente flessibile e le implementazioni standard delle due classi ora descritte
facilmente estensibile presentando punti di estensione può essere possibile ricavare il valore della variabile var1
rappresentati da pluggable classes che all’occasione pos- con una espressione JSF EL del tipo:
sono essere sostituite o decorate (cfr. il pattern Decorator
[GoF] e la Figura 3). #{jndi.var1}
Le classi che costituiscono il core di JSF possono essere
divise in due gruppi: le classi di infrastruttura e le classi dove la variabile var1 è, per esempio, così definita nel
file web.xml:
<env-entry>
<description>Variabile di test</description>
<env-entry-name>var1</env-entry-name>
<env-entry-type>java.lang.Boolean</env-entry-type>
<env-entry-value>true</env-entry-value>
</env-entry>
#{persona.nome}
[1], dovremmo estendere, sempre attraverso un processo riamo un parametro di contesto con il quale si specifica
di decorazione, l’implementazione standard della classe il nome del file di configurazione per il gestore dei dialoghi
ViewHandler. all’interno del quale sarà specificato come le pagine JSP e
Per quanto detto finora si evidenziano alcuni limiti del fra- le classi Java sono tra loro collegate.
mework JSF, ai quali possiamo aggiungere, per maggiore
completezza, l’assenza in JSF di un supporto verso AJAX <context-param>
[2] e l’assenza di validatori client-side. In questo contesto <param-name>org.apache.shale.dialog.CONFIGURATION</param-
si comprende il perché della necessità di Shale. name>
Apache Shale [3], anche noto come Struts 2, è un fra- <param-value>/WEB-INF/dialogo.xml</param-value>
mework che arricchisce JSF con una serie di servizi i quali </context-param>
si possono usare a piacere, in base alle proprie necessità.
Scopo di questo articolo non è descrivere Shale nella sua Shale presenta una serie di dipendenze verso alcuni noti
interezza non potendo esaurire l’argomento in un solo ar- progetti di Apache (i cosiddetti “commons” [8]) e pertan-
ticolo. La Tabella 1 riporta le principali feaures di Shale. to nella directory lib presente all’interno della directory
WEB-INF della applicazione web devono essere presenti
i seguenti jar di queste librerie (per una descrizione det-
Configurazione di Shale tagliata delle dipendenze di Shale verso librerie esterne si
rimanda a [7]). Di seguito indichiamo l’ambiente di runti-
Una volta eseguito il download del framework Shale, me base che supporta Shale:
rimandando a [3] per i dettagli, la sua configurazione è
estremamente semplice. Nel file web.xml della propria ap- • JRE 1.4 o superiore;
plicazione web è sufficiente aggiungere le seguenti righe • Servlet 2.4 e JSP 2.0
di codice: • JSF 1.1 o superiore;
• JSP Standard Tag Library 1.1
<filter> • Apache Commons Bean Utils 1.7 o superiore;
<description>Filtro per Shale</description> • Apache Commons Chain 1.0 o superiore;
<display-name>shale</display-name> • Apache Commons Digester 1.7 o superiore;
<filter-name>shale</filter-name> • Apache Commons Logging 1.0.4 o superiore;
<filter-class>org.apache.shale.faces.ShaleApplicationFilter< • Apache Commons Validator 1.2.0 o superiore.
/filter-class>
</filter> Osserviamo che Shale può funzionare anche con un ap-
plication server che supporta la precedente specifica delle
<filter-mapping> Servlet e delle JSP, ossia la versione 2.3 per le Servlet e 1.2
<filter-name>shale</filter-name> per le JSP (cfr. [7] per i dettagli).
<url-pattern>/*</url-pattern>
</filter-mapping>
Il gestore di dialoghi
le quali definiscono il filtro che analizza le richieste per il
framework Shale. Inoltre, sempre nel file web.xml, dichia- Il modo più semplice ed efficace per rappresentare un dia-
Features Descrizione
View Controller Meccanismo che estende un backing bean associato ad una pagina JSP fornendo al
bean metodi di callback (init(), preprocess(), prerender() e destroy()) invocati in base
ai precisi eventi che si verificano durante il ciclo di vita di una richiesta JSF.
Validazione Integrazione del componente Apache Commons Validator [4] per la validazione sia
lato client che lato server.
JNDI Accesso semplificato, attraverso espressioni JSF EL, alle proprietà definite nel file di
configurazione web.xml.
Dialog Manager Gestore per la realizzazione di wizard per il web, configurato attraverso un file XML
Application Manager Un controller per le richieste HTTP a livello application.
Remoting Supporto server-side al modello di programmazione AJAX
Clay Modulo per il riuso delle pagine HTML in modo simile a Facelets [5] e Tapestry [6];
FIGURA 6 L’editor XML per la definizione dei dialoghi presente nel plug-in Exadel Studio per Eclipse
Riferimenti
Come osservato in precedenza non è necessario sostituire
completamente l’implementazione di default di una classe
pluggable con una nuova classe. Infatti il più delle volte [1] TILEShttp://struts.apache.org/1.x/struts-tiles/index.html
è possibile ed anzi è preferibile aggiungere nuove fun- [2] http://it.wikipedia.org/wiki/AJAXAJAX
zionalità alla classe originale attraverso un processo di [3] http://struts.apache.org/struts-shale/index.html
decorazione (decorator pattern, cfr. [GoF]). Di seguito [4] http://jakarta.apache.org/commons/validator/
riportiamo la firma del costruttore della classe DialogNa- [5] https://facelets.dev.java.net/
vigationHandler: [6] http://jakarta.apache.org/tapestry/
[7] http://struts.apache.org/struts-shale/struts-shale.pdf
public DialogNavigationHandler(NavigationHandler parent) [8] http://jakarta.apache.org/commons/
{
…
this.parent = parent;
Bibliografia
}
Possiamo osservare come al costruttore è passato il riferi- [GoF]: Gamma, Erich, Richard Helm, Ralph Johnson, and
mento dell’implementazione originale del NavigationHan- John Vlissides. 1995. Design Patterns:
dler. Pertanto la classe DialogNavigationHandler delega Elements of Reusable Object-Oriented Software. Pubblicato da
alla classe “parent”, implementazione originale della clas- Addison-Wesley.
se NavigationHandler, in pratica la soluzione della naviga- [JSF]: Kito De Mann. 2005. JavaServer Faces In Action. Pub-
zione quando non si è in presenza di un dialogo, mentre blicato da Manning Publications Co.
gestisce direttamente il nuovo processo di navigazione e
transizione tra gli stati in presenza di un dialogo. La classe
DialogNavigationHandler pertanto decora l’implementa-
zione di default del NavigationHandler.
Conclusioni
In questo articolo abbiamo presentato il framework Shale
basato su JSF. Ovviamente non è sufficiente un solo artico- Note Biografiche
lo per descrivere tutte le features di Shale. Tuttavia risulta Fabio Staro, dottore in Fisica e è Responsabile Tecnico per i pro-
evidente come Shale estenda il modello di JSF fornendo getti Java presso la Direzione Ricerca ed Innovazione di Engi-
neering Ingegneria Informatica S.p.A
servizi e componenti di integrazione. Colpisce di Shale, a
JavaCard
Uno degli oggetti che negli ultimi anni è diventato di uso comune, quasi senza che ce ne accorgessi-
mo, è la smart card. Probabilmente la prima smart card con cui la maggior parte di noi è venuta
in contatto è stata la SIM utilizzata per la telefonia cellulare, seguita a ruota dalle smart card per
l’accesso ai bouquet della TV satellitare, senza dimenticare le nuove generazioni di carte di credito
e di debito.
>> di Matteo Campanella (matteo.campanella@javajournal.it)
N
egli ultimi tempi la pubblica ammi- per alimentare il nostro piccolo computer, una serve
nistrazione sta introducendo delle per dargli il segnale di clock, e altre due servono come
Carte Servizi che presto potranno linee di comunicazione (ingresso e uscita). Ne conse-
facilmente sostituire buona parte dei gue che il lettore di smart card altro non è che un di-
documenti che di solito trovano po- spositivo che alimenta la carta quando viene inserita,
sto nel nostro portafogli. Se a quanto gli fornisce il clock di lavoro, e gestisce lo scambio di
sopra citato uniamo anche la moltitudine di carte di informazioni fra carta e computer host. Per comple-
fidelizzazione cliente e raccolta punti, ci possiamo tezza bisogna aggiungere che esistono anche delle
fare un’idea concreta di quanto sia diventato vasto smart card che non hanno logica programmabile
questo mondo, e di quanto la smart card faccia or- all’interno, ma sono solo delle memorie.
mai parte integrante della nostra vita. Vale la pena di
ricordare che, sebbene ci possano apparire come un Le Smart Card rispondono ad uno standard ben pre-
fenomeno relativamente recente, la prima smart card ciso, che è l’ISO 7816 – esso ne fissa le dimensioni
è stata creata nel lontano 1974, da Roland Moreno; fisiche, le caratteristiche elettriche e i dettagli del
di contro quest’anno sono state prodotte quasi un protocollo di scambio dati. Sebbene le modalità di in-
miliardo di smart card, con una spiccata supremazia terazione con una smart card rimangono ben identi-
di Europa ed Asia (95%) sugli USA (5%). ficate da questo standard (il che riveste fondamenta-
le importanza per l’interoperabilità), ogni produttore
è libero di implementare i dettami della ISO 7816
nel modo che più gli aggrada, un po’ come succede
con Java per il quale Sun Microsystems detta solo le
specifiche, demandando a chiunque sia interessato lo
sviluppo di una JVM ad esse rispondente.
Una delle principali conseguenze di ciò è che ogni
costruttore è libero di mettere a punto un ambien-
te di sviluppo e un insieme di API, o addirittura un
linguaggio di programmazione, che risponde alle
proprie esigenze e non ad uno standard.
1. Specifiche della Java Virtual Machine; dinamico delle classi, il security manager, i thread e la sin-
2. Specifiche del Java Runtime Environment; cronizzazione non sono supportati, così come alcuni tipi di
3. API per la piattaforma Java Card dato complessi come float, double, e char. Affinché l’instal-
lazione di un’applet possa andare a buon fine, è necessario
Riassumendo, la Java Card è essenzialmente una smart che essa implementi un metodo public static install, che vie-
card in grado di eseguire programmi Java. Le specifiche ne chiamato dal Runtime Environment come ultimo passo
prevedono delle risorse hardware veramente esigue: 16KB della procedura di installazione.
di ROM, 8KB di EEPROM e appena 256 bytes di RAM.
L’esecuzione del bytecode Java è possibile grazie all’im-
plementazione di una Java Virtual Machine direttamente
sullo strato di sistema operativo della smartcard, di cui
nasconde completamente gli aspetti peculiari; chi svilup-
LaJava Card è es-
pa per Java Card non si deve preoccupare di quale sia il
produttore; basta attenersi alle specifiche dell’API e non ci
senzialmente una smart
saranno sorprese. Attenzione però, a volte potrebbe venire
la tentazione di utilizzare delle estensioni alle API stan- card in grado di eseguire
dard fornite dal produttore della card al fine di sfruttare
peculiarità della carta: niente di male, si tratta di un passo programmi Java
in alcuni casi indispensabile, ma di fatto pone fine alla
completa portabilità del codice – non è infatti detto che
un altro fornitore abbia implementato le stesse estensioni
(Figura 1). Tutte le applet registrate su una Java Card sono candidate
a fornire servizio, e di conseguenza è necessario che esista
un meccanismo con cui si possa comunicare alla card quale
Come funziona una Java Card? delle applet installate deve essere mandata in esecuzione.
Le Java Card supportano il protocollo di comunicazione fra
Per poter girare su una Java Card, le applet vi devono la card e il lettore così come da specifiche ISO7816; questo
essere preventivamente installate. Non si pensi di avere protocollo prevede l’uso di pacchetti per la comunicazione,
a disposizione tutta la potenza di Java: il caricamento chiamati APDU (Application Protocol Data Units). La card
package it.mc.jctest; }
LISTATO 2 TalkTimerEngine
L’importo da accreditare è specificato nel campo Data, la L’importo da addebitare è specificato nel campo Data, la
SW dice se l’accredito è andato a buon fine o meno (ad SW dice se l’addebito è andato a buon fine o meno (ad
esempio, il borsellino è troppo pieno). esempio, il borsellino non contiene abbastanza crediti).
Addebito Giacenza
APDU di comando: CLA=0x60, INS=0x62, P1=0x00, APDU di comando: CLA=0x60, INS=0x63, P1=0x00,
P2=0x00, Lc=0x01, Data=importo, Le=0x0 P2=0x00, Lc=0x00,Data=null, Le=0x2
APDU di risposta: Dati=null, SW1-SW2=0x9000 (OK), APDU di risposta: Dati=giacenza, SW1-SW2=0x9000
0x6A00 (KO) (OK)
Poiché si tratta di un comando di interrogazione non sono Non ci soffermeremo sul metodo addebito(APDU), poiché
previsti parametri passati in chiamata; ci si aspetta che i esso è del tutto simile al precedente, eccezion fatta per la
due byte rappresentativi della giacenza vengano ritornati logica di aggiornamento della giacenza.
nel pacchetto di risposta (Listato 1).
Vediamo quindi il metodo giacenza(APDU apdu), partico-
La classe Borsellino (che deve estendere la classe javaca larmente interessante in quanto illustra come un metodo
rd.framework.Applet) comincia con la dichiarazione del- possa passare delle informazioni al “client” della carta (in
le variabili corrispondenti ai CLA, agli INS e ai codici di questo caso la giacenza del borsellino). Analogamente a
errore dell’applicazione, così come definiti nel paragrafo quanto visto prima, poiché il campo Dati nell’APDU di
precedente. Il contenuto del borsellino è mantenuto nella riposta è opzionale, è necessario che quest’ultimo venga
variabile a 16 bit giacenza. Segue il costruttore dell’Applet, predisposto mediante il metodo setOutgoing(), che ritorna il
chiamato dal metodo install(), che da specifiche deve numero di byte del campo, uguale al campo Le dell’APDU
preoccuparsi di effettuare tutte le inizializzazioni peculiari di comando. In successione si invocano poi i metodi se-
dell’applicazione e di chiamare il metodo register(). In breve tOutgoingLength() passando come argomento il numero
quindi il JCRE (Java card Runtime Environment) all’atto di byte e sendBytes() passando come argomenti l’offset a
dell’installazione dell’applet Borsellino chiama il metodo cui trovare i dati nel vettore buffer e il numero di byte da
install() che crea una nuova istanza dell’Applet, la quale trasmettere.
nel costruttore deve contenere la chiamata al metodo
register(). Poiché può esistere una sola istanza per applet,
il metodo install() può essere chiamato con successo una
sola volta.
S
prattutto se si vogliono introdurre delle ottimizza-
i tratta di un’altra Java Virtual Machi- zioni.
ne? Questa domanda sorge spontanea: Come se non bastasse un JIT efficiente risulta esse-
in effetti tramite i vari tool che accom- re molto complesso e di conseguenza richiede una
pagnano gcj è possibile compilare ed quantità sensibile di memoria, il che può non essere
eseguire del codice Java, esattamente un problema su un desktop od una workstation con
come avviene utilizzando la JVM della Sun. Ma una memoria di svariate centinaia di megabyte, ma
allora dove sta la differenza? è sicuramente un fattore rilevante in un sistema
embedded. Infine Java nella sua implementazione
classica non ha una buona interoperabilità con altri
Funzionamento classico di una JVM linguaggi: le chiamate fra Java e C/C++ sono lente
e non banali.
L’approccio tradizionale a Java è caratterizzato da
due fasi: una fase di traduzione ed una di esecuzione.
Il codice sorgente viene compilato tramite il pro-
gramma javac, che produce una serie di file .class
contenenti la rappresentazione binaria delle infor-
La
tecnica utilizzata
mazioni relative ad una classe. Queste informazioni
sono tradotte in bytecode: il set di istruzioni di una da Gcj prende il nome di
macchina virtuale basata su stack.
La fase di esecuzione viene gestita da una JVM “Ahead of time
(Java Virtual Machine) che ha il compito di leggere
ed interpretare i file .class creati precedentemente. compilation”
Una JVM può essere vista come un emulatore di
una macchina il cui set di istruzioni è il Java byte-
code.
Abbiamo usato SciMark2 (http: Per maggiore completezza il test Il vantaggio che consegue dalla compilazio-
//math.nist.gov/scimark2) per è stato effettuato in entrambi i ne nativa non è tanto la velocità, quanto un
effettuare un veloce benchmark modi. miglioramento nell’utilizzo della memoria.
che prendesse in esame velocità Gli sforzi profusi nel miglioramento dei JIT
ed utilizzo di memoria di gcj (v. Velocità di esecuzione compiler li ha resi estremamente efficienti,
4.0.2) e Sun JDK 1.5. Modalità normal: tanto che in determinate situazioni possono
• Sun JDK: 27415 ms essere più prestanti rispetto a codice nativo
I test sono stati eseguiti su un • Gcj: 29248 ms poiché effettuano delle ottimizzazioni in
Athlon 1000 equipaggiato con base al contesto attuale. Questo non è fat-
768 Mb di RAM ed è stato uti- Modalità large: tibile con la “ahead of time compilation”
lizzato il pacchetto jar disponi- • Sun JDK: 63188 ms poiché la compilazione avviene in una fase
bile al download sul sito di Sci- • Gcj: 60324 ms precedente a quella dell’esecuzione; di con-
Mark. seguenza il compilatore non ha informazioni
Il tempo di esecuzione è stato Utilizzo di memoria sullo stato attuale della macchina e non può
misurato utilizzando il coman- quindi effettuare ottimizzazioni dipendenti
do time, per l’utilizzo di memo- Modalità normal dal contesto. In generale, comunque, un
ria ci si è invece affidati a ps. eseguibile nativo risulta più veloce in fase di
Imple- VM Size VM RSS inizializzazione (Riquadro 1) .
L’eseguibile nativo è stato com- menta- (kb) (kb)
pilato con queste opzioni: zione
gcj –main=jnt.scimark2. Non soltanto un compilatore
commandline -O3 -o sci- Sun JDK 261436 10472 Gcj non è soltanto un compilatore. È un am-
mark scimark2lib.jar 1.5 biente Java completo, paragonabile al JDK
della Sun. Assieme al compilatore vengono
Le prove sono state effettua- Gcj 4.0.2 30188 12684 forniti un interprete di bytecode ed una serie
te invocando scimark in que- di librerie d’appoggio che completano l’am-
sto modo: Modalità large biente. Il cuore pulsante di gcj risiede nella
• Nativo: ./scimark sua runtime-library: libgcj. Quest’ultima si
• Interpretato: Imple- VM Size VM RSS occupa di gran parte del lavoro, offrendo un
java -cp scimark2lib.jar menta- (kb) (kb) garbage collector, l’interprete di bytecode e
jnt.scimark2.commandline zione un ClassLoader capace di gestire sia librerie
native che file .class.
SciMark2 può essere eseguito Sun JDK 260412 70364
in due modalità: normal e large. 1.5 La Tabella 1 riporta l’equivalente di alcuni
La scelta di una piuttosto che dei tool disponibili nel JDK della Sun.
l’altra determinerà la comples- Gcj 4.0.2 94936 77692
sità computazionale del test.
Prima compilazione
RIQUADRO 1 Un semplice benchmark sulle prestazioni in termini di
velocità di esecuzione ed utilizzo di memoria di gcj e del Sun JDK 1.5 Adesso che abbiamo un idea di cos’è e di
quello che è capace di fare, sporchiamoci le
• Compilazione da bytecode ad istruzioni macchina mani con la prima compilazione nativa tramite gcj. Come
primo esempio ci avvarremo del codice riportato nel Li-
La vera potenza di gcj risiede però nella possibilità di stato 1, che stampa sullo standard output la famosa
utilizzare soluzioni miste: le vostre applicazioni potran- frase: Hello World!
no essere composte da porzioni compilate nativamente Per rendere il tutto più interessante useremo due classi
ed altre interpretate! Questa caratteristica fa di gcj uno interdipendenti.
strumento veramente flessibile, che si adatta facilmente
alla esigenze più disparate. Il processo che porta ad ottenere un eseguibile si divide in
due parti, la compilazione ed il linking. Per chiunque
abbia usato almeno una volta il compilatore gcc la
Sun JDK GNU Gcj prima fase risulterà molto familiare, per quanto ri-
javac gcj -C guarda seconda invece ci sarà qualche novità.
java gij
javadoc gjdoc La prima cosa da fare è istruire gcj su quali file desi-
deriamo vengano convertiti in linguaggio macchina:
javah gcjh
javap jcf-dump gcj -c HelloWorld.java Printer.java
TABELLA 1 Corrispettivi Sun JDK Questo comando farà si che i sorgenti vengano
gcj –main=HelloWorld -o hello HelloWorld.o Printer.o In determinate situazioni risulta conveniente compilare
porzioni di codice in librerie condivise, così da ottimizzare
Come accennato precedentemente, gcj necessita di un l’utilizzo di memoria (sia primaria, che secondaria). Per
parametro aggiuntivo rispetto a quanto accade per gcc. ottenere questo scopo gcj utilizza lo switch -shared, oltre
In C/C++ un programma può essere composto da più ad una serie di opzioni aggiuntive non strettamente ne-
file ma solamente uno di questi può contenere il metodo cessarie che però portano a delle ottimizzazioni a vari
main, di conseguenza il linker è sempre in grado di capire livelli. Per proporre un esempio pratico, compiliamo
da solo quale è la porzione di codice che deve essere ese- Printer.java come libreria dinamica ed agganciamolo a
guita inizialmente. HelloWorld.
In Java invece è pratica comune creare diversi metodi La prima fase ora si svolge in due parti:
1. compilazione di Printer.java
come libreria dinamica
2. compilazione canonica di
HelloWorld.java
LISTATO 2 Sorgenti della nostra applicazione e Per chiarirci le idee osserviamo il Listato 2, in cui
dei due moduli, Foo e Bar. Il primo verrà compilato in possiamo vedere un’applicazione che carica dinami-
bytecode, l’altro nativamente camente tramite Class.forName due moduli esterni,
dei quali uno verrà compilato nativamente, l’altro
tazione ottimizzata di gcj per l’accesso ai metodi nativi) in bytecode.
che sarebbe altrimenti utilizzato per default. Quest’ulti-
mo parametro non è influen-
te sul nostro esempio poiché
non viene fatto uso di metodi
nativi, ma in presenza di que-
sti è molto probabile che tale
opzione si renda necessaria.
Un eventuale omissione por-
terebbe ad avere diversi errori
in fase di linking.
gcj –main=HelloWorld -o
shello HelloWorld.o -lprinter
gcj -shared -fPIC -o lib-it-javajournal-Bar.so In entrambi i casi la libreria si deve trovare all’interno
it/javajournal/Bar.java del path del linker, pena il lancio di un’eccezione Clas-
sNotFoundException , nel primo caso, o un errore in fase di
A questo punto passiamo alla compilazione del corpo compilazione nel secondo.
dell’applicazione:
Un compilatore non basta
gcj –main=it.javajournal.App -o app it/javajournal.App.java Gli strumenti necessari per sviluppare ed eseguire un
programma Java sono fondamental-
mente tre:
• un compilatore
• una Virtual Machine/Runtime
library
• le librerie contenti il codice fornito
con J2SE/J2EE
Gnu Classpath
Gcj Binary Compatibility ABI Questo tool genera un file .db che mappa una versione
compilata di una classe, alla sua controparte in bytecode.
Alcune applicazioni sono scritte assumendo che verrano Durante la compilazione nativa, quando gcj incontra de-
eseguite solamente all’interno di una Virtual Machine, fineClass(), il bytecode passato viene confrontato (trami-
facendo assunzioni sull’ambiente in cui si trovano. Que- te la mappa contenuta nel file .db) con le librerie dinami-
sta pratica rende molto complicato compilare tali pro- che contenenti le classi native.
grammi nativamente, a meno di pesanti modifiche al co- Perché durante l’esecuzione gcj sappia quale file .db usare
dice sorgente. è necessario specificare tramite la proprietà gnu.gcj.preco
Nello specifico questi programmi contengono il codice per mpiled.db.path il percorso di quest’ultimo.
leggere stream di bytecode e caricarli come classi tramite il Grazie a questo meccanismo, gcj è in grado di utilizzare la
metodo ClassLoader.defineClass(). Un esempio molto cono- versione nativa della classe in questione, al solo costo di
sciuto di tali applicazioni, in cui praticamente tutte le com- mantenere anche la versione in bytecode.
ponenti sono caricate in questo modo, è Eclipse. Il flag -findirect-dispatch attiva l’ABI per la compati-
Il problema che questa pratica comporta a gcj è molto bilità binaria. Quest’ultima oltre ad essere necessaria
semplice: non esiste bytecode per una classe compilata per il funzionamento del meccanismo descritto poc’an-
nativamente e di conseguenza non è possibile creare uno zi, porta benefici a tutte le applicazioni, garantendone
stream da passare al ClassLoader. il funzionamento anche nel momento in cui venissero
Per ovviare a questo problema gcj v.4 ha introdotto una introdotti cambiamenti alla libgcj, senza bisogno di ri-
nuova modalità di compilazione, attivabile tramite lo swith compilare. In futuro diventerà il metodo di compilazio-
-findirect-dispatch ed un nuovo strumeto: gcj-dbtool. ne standard.
Java ME
sviluppare applicazioni
per cellulari e PDA
Java Micro Edition (Java ME) è la piattaforma leader per lo sviluppo di applicazioni multidevi-
ce per telefoni cellulari, palmari e dispositivi embedded. Grazie ad una architettura modulare e ad
una ricca collezione di API opzionali, in soli 5 anni ha conquistato il mercato dei dispositivi mobili
e si appresta alla soglia del miliardo di terminali abilitati già in circolazione. In questo articolo in-
troduciamo questa affascinante tecnologia.
>> di Stefano Sanna (stefano.sanna@javajournal.it)
L
di unità vendute, 150 operatori di telefonia mobile e
più di 350 mila sviluppatori nel mondo supportano
a storia del linguaggio Java inizia nei la piattaforma, mentre mensilmente vengono scari-
primi anni ‘90, grazie ai risultati del cate sui telefonini 23 milioni di applicazioni.
brillante Green Project. L’obiettivo
della semplicità nella scrittura del
codice e di alta portabilità tra diverse Configurazioni e Profili
architetture hardware portarono alla
definizione del linguaggio Oak e alla Rispetto agli ambienti desktop e server, il mondo dei
realizzazione dell’innovativa piattaforma “*7” (la dispositivi mobili è straordinariamente vario. Nume-
prima applicazione di Java) . Inizialmente si mirava rose le combinazioni di sistemi operativi (proprietari
al settore della TV via cavo, ma quanto fino ad al- e non), piattaforme hardware, classi di dispositivi,
lora ottenuto apparve particolarmente efficace per mercati di riferimento: una architettura monolitica
risolvere un problema emergente, complice la ina- non potrebbe abbracciare un’offerta così vasta. Al
spettata e rapida diffusione del web: la possibilità fine di essere adattata al maggior numero di tipi di
di distribuire codice applicativo insieme alle pagine dispositivi, la piattaforma Java ME è organizzata in
web (codice embedded, ancora una volta!) con il livelli componibili e, in certa misura, intercambiabili.
requisito di avere portabilità tra diverse piattaforme In questo modo i produttori dei dispositivi possono
hardware (in teoria qualsiasi PC dotato di un web decidere, in base alle funzionalità supportate dal-
browser, all’epoca Netscape). Nacque Java e le Ap- l’hardware e agli obiettivi di mercato, quali livelli im-
plet: fu l’inizio di una nuova classe di applicazioni. plementare e, dunque, adattare il runtime Java. Tale
Negli anni successivi il linguaggio e la libreria stan- modularità è ottenuta attraverso una organizzazione
dard sono stati arricchiti, portando la tecnologia in Configurazioni, Profili ed API opzionali.
Java in ambiti quali le applicazioni desktop e i servi-
zi enterprise che sembravano appannaggio solo del
software scritto in codice nativo (C/C++). Proprio
in ambito server, invece, con la piattaforma J2EE,
Java ha dimostrato di essere una tecnologia estre-
La piattaforma
mamente potente, flessibile e robusta. Nel 2001 (6
anni dopo il rilascio delle prime specifiche Java)
Java ME è organizzata
vennero rese pubbliche le prime implementazioni di
CLDC e MIDP: nasceva la piattaforma Java2 Micro in livelli componibili e
Edition (J2ME), rinominata lo scorso anno Java
Platform, Micro Edition (Java ME). Il ritorno al intercambibili
settore embedded/consumer è un successo straordi-
nario e i numeri lo confermano: 650 modelli di ter-
minali Java ME compatibili, con più di 700 milioni
per l’implementazione del supporto alla connettività. Profile) e PP (Personal Profile). Presi nell’ordine, aggiun-
Esso permette di aggiungere il supporto a nuovi sistemi gono funzionalità sempre più complesse alla configura-
di comunicazione (ad esempio, Bluetooth o messaging) zione, a partire dalla GUI elementare di FP fino alla im-
senza che sia necessario modificare la gerarchia standard plementazione completa di AWT fornita da PP. Il Personal
delle classi e garantendo, entro certi limiti, massima com- Profile può essere riconosciuto, da chi (come l’autore) ha
patibilità delle applicazioni (Figura 1). lavorato fin dalle prima implementazioni di Java su PDA,
come il successore del PersonalJava, il primo tentativo
storico di realizzare un Java per dispositivi embedded.
I profili sono la
Panoramica di MIDP 2.0
specializzazione per uno
MIDP è il profilo supportato dalla maggior parte dei
specifico prodotto terminali in circolazione; in particolare, la versione 2.0
equipaggia la totalità dei modelli di nuova commer-
(o insieme di prodotti) cializzazione (di seguito si farà riferimento a questa
versione). MIDP fornisce il supporto alla connettività
via HTTP (requisito minimo), persistenza sulla memo-
ria del dispositivo, interfaccia grafica a componenti,
set minimale di classi per la riproduzione di contenuti
Profili: MIDP e gli altri multimediali, classi accessorie di supporto allo svilup-
po della grafica dei videogiochi (tali classi sono cono-
Mentre le configurazioni stabiliscono le caratteristiche sciute con il nome di Game API). Le classi specifiche
comuni a una certa famiglia di hardware, i profili sono la della piattaforma Java ME sono contenute nei package
specializzazione per uno specifico prodotto (o insieme di javax.microedition.*. La prima particolarità rispetto alla
prodotti). Sulla CLDC sono basati i profili MIDP e IMP. Il piattaforma standard è la gestione del ciclo di vita delle
profilo MIDP (Mobile Information Device Profile) è desti- applicazioni. Queste sono chiamate MIDlet e sono ge-
nato ad equipaggiare telefoni cellulari e computer palma- stite dall’Application Manager del dispositivo, respon-
ri di classe consumer. Il profilo IMP (Information Module sabile della installazione, rimozione, avvio, sospensione
Profile), viceversa, è destinato al mercato dei controllori e interruzione di ciascuna applicazione. L’interfaccia di
embedded avanzati; esso, dunque, è destinato ad essere gestione dell’Application Manager dipende dal disposi-
installato in macchinari e strumenti per i quali siano tivo in uso mentre l’interazione con la MIDlet è gestita
necessarie funzionalità di programmabilità, elaborazione attraverso l’invocazione del costruttore e di tre metodi
di segnali analogici e digitale, controllo di attuattori (ad accessori. Il costruttore della MIDlet viene invocato al
esempio, motori) e soprattutto di connettività su rete IP primo caricamento dell’applicazione, mentre all’avvio
(generalmente attraverso rete telefonica GPRS). Si può vero e proprio l’Application Manager invoca il metodo
pensare a IMP come ad una specializzazione di MIDP, in startApp(). Questo metodo potrebbe essere invocato più
cui è stata eliminata la sezione dedicata all’interfaccia volte durante la vita dell’applicazione: in caso di neces-
grafica (generalmente inutile o comunque sostituita da sità, infatti, l’Application Manager potrebbe richiedere
hardware dedicato) e aggiunta la gestione degli input e all’applicazione di sospendere l’esecuzione (attraverso
output analogici e digitali. Su CDC si basano attualmente l’invocazione del metodo pauseApp()) per poi riprenderla
tre profili: FP (Foundation Profile), PBP (Personal Basis in seguito. Infine, l’invocazione del metodo destroyApp()
FIGURA 3 Il TalkTimer in esecuzione nel Wireless Toolkit, nella Nokia Developer’s Suite e su Windows Mobile 2003
(attraverso remote display)
MIDlet-1: TalkTimer, TalkTimer.png, it.javajournal stione fornito dal produttore del terminale (dunque con
.talktimer.TalkTimer il supporto di un PC), via Bluetooth o Infrarossi (tecni-
MIDlet-Jar-Size: 3528 camente detto OBEX Push, modalità non supportata da
MIDlet-Jar-URL: TalkTimer.jar tutti i terminali).
MIDlet-Name: TalkTimer
MIDlet-Vendor: My Company
MIDlet-Version: 1.0
La prima applicazione Java ME
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-2.0 Le classi di MIDP 2.0 permettono di realizzare appli-
cazioni di media complessità, dotate di supporto alla
Attraverso queste informazioni, prima di scaricare il file connettività HTTP, persistenza sul dispositivo e grafica in
JAR, l’Application Manager può determinare la com- movimento. Per prendere confidenza con la piattaforma
patibilità del runtime e segnalare all’utente eventuali Java ME è sufficiente scrivere una MIDlet semplice ma
anomalie. Ad esempio, una applicazione basata su CLDC efficace. Si vuole realizzare un semplice timer (TalkTi-
1.1 (con supporto dell’aritmetica in virgola mobile), non mer), da utilizzarsi, ad esempio, durante un seminario:
verrà eseguita su un dispositivo CLDC 1.0. Il file JAD vie- il relatore, all’inizio della presentazione avvierà l’appli-
ne creato automaticamente dai tool di sviluppo Java ME; cazione, impostando la durata del proprio intervento.
essi provvedono anche a replicare le informazioni del file Durante l’esposizione potrà verificare sul display il tempo
JAD all’interno del file MANIFEST del JAR (con l’esclu- a sua disposizione e al termine di quest’ultimo un segnale
sione dell’URL di quest’ultimo). sonoro lo avviserà. La classe di avvio, TalkTimer, estende
MIDlet e inizializza la classe TalkTimerEngine, responsa-
L’installazione dell’applicazione sul dispositivo può avve- bile della gestione dell’interfaccia grafica e del timer vero
nire con diverse modalità: attraverso download via web/ e proprio (Listato 1)
wap (detto OTA, Over-The-Air, che indica il trasferimento
effettuato su canale radio), per mezzo del software di ge- Nel costruttore viene istanziata la classe responsabile
API Descrizione
Wireless Messaging API 1.1 e 2.0 (WMA, Permette l’invio e la ricezione di brevi messaggi, sia in
JSR 120, 205) formato testo che binario. Probabilmente è l’API opzionale
maggiormente diffusa, anche su modelli entry-level (WMA
2.0 solo su terminali di fascia alta).
Mobile Media API (MMAPI, JSR 135) Fornisce il supporto base per la riproduzione e l’acquisizione
di contenuti multimediali audio e video.
Mobile 3D Graphics (M3G, JSR 184) Implementa una ricca libreria per la grafica 3D. Sono stati
annunciati cellulari con accelerazione hardware per la M3G.
Java APIs for Bluetooth (BTA, JSR 82) Fornisce i meccanismi per il discovery di device e servizi
Bluetooth. OBEX e SPP tra i servizi supportati.
Location API (JSR 179) Permette lo sviluppo di applicazioni basate sulla posizione,
con una interfaccia astratta verso sistemi di localizzazione
mobile e gestione landmark.
FileConnection & PIM API (JSR 75) Si tratta di funzionalità opzionali ereditate dal PDAP
(Pda Profile), che avrebbe dovuto affiancare MIDP nel
supporto Java su palmari e telefoni hi-end. In realtà PDAP
non vide mai la luce e dalla specifica rimasero questi due
importantissimi package, che forniscono supporto ai servizi
di Personal Information Management (PIM) e al file system
del dispositivo.
Scalable 2D Vector Graphics API (JSR 226) Fornisce supporto alla gestione e visualizzazione di file SVG.
Web Service API (WSA, JSR 172) Implementa le funzionalità di parsing XML e invocazione
di metodi remoti su interfaccia Web Service conforme alle
specifiche WS-I Basic Profile 1.0
TABELLA 1
LISTATO 2 TalkTimerEngine
della gestione dell’interfaccia grafica, mentre la visua- con metodi per la sospensione e la ripetizione ciclica
lizzazione avviene all’interno del metodo startApp(). Il temporizzata di blocchi di codice (contenuti all’interno
metodo setCurrent() del display assegnato alla MIDlet del classico metodo run()). Il metodo commandAction(),
permetterà la visualizzazione del Form iniziale. Quest’ul- definito nell’interfaccia CommandListener, è invocato dal
timo è implementato dalla classe TalkTimerEngine (visi- runtime alla pressione di un bottone del cellulare (det-
bile in Listato 2), la quale gestisce gli eventi della gui ed to softbutton) assegnato al Command. La selezione del
è incaricata dell’avvio e arresto del timer. Il metodo init() Command “start” provoca l’assegnazione del TimerTask
provvede a istanziare i componenti e assemblare l’inter- definito nel metodo init() all’interno dello scheduler del
faccia grafica del Form (Listato 2). Timer. Ogni 60 secondi, il Task verificherà se è trascorso il
tempo a disposizione ed eventualmente, attraverso il me-
All’interno dello stesso metodo si definisce un Timer- todo alarm(), notificherà all’utente il timeout attraverso
Task: questo, unito alla classe Timer, costituisce una l’emissione di un breve tono (Figura 3).
specializzazione delle classi Thread e Runnable, arricchiti
Le
Java ME è necessario utilizzare strumenti dedicati. Ri-
spetto a Java SE, le applicazioni per dispositivi mobili, applicazioni mo-
prima di essere distribuite, passano attraverso un pro-
cesso di preverifica; questo è operato dalla Java Virtual bile, prima di essere di-
Machine standard in fase di esecuzione, mentre in ambi-
to MIDP le ridotte prestazioni dei dispositivi impongono
che parte della verifica del bytecode sia effettuata prima
stribuite, passano per un
del rilascio definitivo. Il runtime Java effettua comunque
dei controlli, anche se meno onerosi e complessi della
processo di preverifica
preverifica. Il passo successivo è l’esecuzione all’interno
di un emulatore, che permette una prima valutazione
dell’applicazione e facilita il debugging. Per CLDC/MIDP
Sun Microsystems fornisce il Java Wireless Toolkit
(WTK), una collezione di tool a linea di comando e una Conclusioni
utility grafica per la compilazione, preverifica e packaging
dell’applicazione. Per realizzare una nuova applicazione è Dal 2001 ad oggi la piattaforma Java ME è cresciuta no-
sufficiente creare un nuovo progetto e indicare il nome tevolmente sia per numero di terminali installati (siamo
(completo di package) della MIDlet. Il WTK associa una prossimi al miliardo di unità!) che per la ricchezza del
directory all’interno del proprio repository, contenuto runtime environment con tutte le API opzionali. Questa
nella directory ROOT_WTK\apps (ROOT_WTK è la car- maturità permette agli sviluppatori di realizzare applica-
tella di installazione del WTK). Il codice sorgente deve zioni a supporto della totale mobilità degli utenti, con
essere salvato nella sottodirectory src, mentre risorse e ricco supporto alla connettività (messagging, Bluetooth,
librerie opzionali troveranno collocazione rispettivamen- IP su rete telefonica e WiFi, web service). Dal 2006 sono
te in res e lib. Attraverso i menù BUILD, RUN e CREATE annunciate nuove API e dispositivi dalle prestazioni ele-
PACKAGE è possibile compilare il codice, eseguirlo all’in- vatissime: l’auspicio è quello di avere una nuova classe di
terno dell’emulatore standard e creare i file JAD e JAR per applicazioni a supporto della mobilità degli utenti consu-
il deployment finale. mer, fortemente connesse e georeferenziate.
Java 5, le buone
nuove e le novità
meno buone
prima parte
Scrivere nel 2006 un articolo sulle novità di Java5 può sembrare un po’ fuori tempo massimo, poi-
ché Sun ha presentato questa release nel 2004, e Java6 è ormai dietro l’angolo. Ma ci sono da tenere
in considerazione diversi aspetti che giustificano questo argomento.
V
fidabilità, mantenendo la compatibilità all’indietro.
ediamo dunque perché trattare le novità Particolare attenzione in questa release è stata posta
di Java5: sull’incremento delle performance: alcuni obiettivi
• le novità introdotte in Java5 non sono iniziali sono invece stati parzialmente rischedulati
state ancora ben digerite da molti svilup- per Java6. L’obiettivo di questo articolo invece è pas-
patori. Per lavoro mi capita di vedere molto codice sare in rassegna le novità, con un accento particolare
Java scritto da altri, ed è comune – molto comune - su quelle che hanno fatto meno clamore.
imbattersi in idiomi ormai resi obsoleti dalle nuove Possiamo raggruppare le novità con l’ausilio della
versioni del linguaggio. Di fatto, spesso non vengo- Tabella 1. Ovviamente la tabella è riduttiva, ci sono
no utilizzate neanche le features di Java 1.4 (per i centinaia di cambiamenti (più o meno piccoli) nelle
non avvezzi alle simpatiche regole del marketing, API e nei tool di supporto [ENHANCEMENTS]. Però
java 1.4 è la release precedente a java5) ce n’è già abbastanza per scrivere un articolo e lascia-
• un cambiamento così grande (mi piacerebbe usare re fuori un sacco di dettagli! Prima di soffermarci sui
l’aggettivo epocale, ma suonerebbe troppo sensa- vari cambiamenti, assicuratevi di usare il compilatore
zionalista) non c’era mai stato e non ci dovrebbe passandogli lo switch per il sorgente 1.5 (-source 5),
mai più essere: il nuovo processo di rilascio delle su alcune “vecchie” versioni di javac il default per
versioni di Java e la relativa tempistica – circa 2 questo switch era ancora 1.4.
anni per major release - rende improbabile cambia-
menti drastici da una release all’altra. Da java 1.4 a Generics
Java5 sono infatti passati ben 4 anni.
• Diversi cambiamenti sono argomento di discus- Sicuramente è la novità apparentemente più impor-
sione giornaliero sui forum. Per molti di essi non tante, e quella sulla quale se ne è scritto di più. È
c’è ancora una chiara posizione della comunità: le anche uno dei costrutti più complessi e meno cono-
Annotations API sono effettivamente utili o peg- sciuti, con molti “angoli bui”
giorano il design? In sostanza, i generics non sono altro che una tecnica
• Java6 non introdurrà nessun cambiamento parti- per ottenere una maggiore type safety in java. In un
colare, ma apporterà solo miglioramenti a diverse linguaggio strongly typed come java, questo non può
API, concentrandosi in particolare sul Desktop. che essere un bene. Usando infatti le nuove tecniche
Java5 ha introdotto nuove keyword nel linguag- si risparmieranno molti cast ed il codice sarà teori-
gio e anche nuove api che rendono praticamente camente più robusto. Uso “teoricamente” perchè
obsolete alcune parole chiave (si pensi alle nuove personalmente non mi è mai capitato un bug dovuto
concurrent api, per esempio) all’inserimento in una collection di un oggetto erra-
Penso di essermi giustificato abbastanza, per cui to, ma diamo atto che un controllo in più fatto dal
passiamo in rassegna le novità. L’obiettivo principale compilatore non può che essere un buon controllo.
del team di Java5 è stato quello di migliorare la leggi- “Making Java easier to type and easier to type”, re-
bilità del codice e aumentarne allo stesso tempo l’af- citava con un simpatico gioco di parole lo slogan di
people.add(“Luca Landini”);
Pizza/GJ [PIZZA], il precursore dei generics in Java5. // ...
È vero infatti che per anni una parte della comunità Java String luca = people.get(2);
ha lamentato l’assenza dei generics (e proprio per questo
qualcuno sentì la necessità di creare Pizza/GJ), mentre Come si vede chiaramente dal codice, non c’è più bisogno
un’altra parte ne ha sempre osteggiato l’inserimento, fa- di fare un cast dopo il get(). È infatti garantito che nella
cendo presente soprattutto la complessità e la macchinosi- collection people ci siano solo delle String, ed un tentativo
tà dei template in C++. James Gosling è sempre stato con- di inserimento di un oggetto del tipo sbagliato sarebbe
trario, ma questa è proprio la dimostrazione che il processo individuato addirittura in fase di compilazione (e non a
che guida l’evoluzione della piattaforma Java (Java Com- runtime).
munity Process, JCP) è abbastanza democratico, oppure è
la dimostrazione che Gosling sta perdendo smalto).
Sia come sia, in Java5 queste feature sono lì e non possono
essere ignorate, soprattutto perchè le API sono state tutte
genericizzate, quindi perlomeno bisogna avere una qualche
Peranni una parte
confidenza con esse. Fra l’altro nell’implementazione che è
stata poi scelta, hanno molto poco a che vedere con quanto della comunità Java ha
a disposizione in C++.
lamentato l’assenza dei
// ...
List people = new ArrayList(); generics
people.add(“Ugo Landini”);
people.add(“Diego Landini”);
people.add(“Luca Landini”);
// ... Poniamo ad esempio che si provi ad inserire uno StringBui-
String diego = (String)people.get(1); lder invece di una Stringa: il compilatore si lamenterebbe
poichè non riuscirebbe a trovare il metodo add(StringBuilder)
Questo codice è ormai legacy, sostituito dal codice seguente all’interno dell’interfaccia List! A questo punto le doman-
de sorgono spontanee... come fa a funzionare? Il metodo
// ... add() di List non accettava Object come parametro? Esi-
List<String> people = new ArrayList<String>(); ste una classe List<String> con un add(String) ed una
people.add(“Ugo Landini”); List<StringBuilder> con un add(StringBuilder)? Come è
people.add(“Diego Landini”); possibile?
TABELLA 1
Per padroneggiare questo meccanismo, è necessario ca- può fare con il tipo. Ad esempio, essendoci una sola classe,
pire come si dichiara un tipo parametrico, e come viene i metodi statici – che appartengono alla classe e non alle
compilato di conseguenza il bytecode. Si vedrà che quella istanze - non possono usare il tipo in alcun modo!
complessità che è in qualche modo sparita dal codice che La cosa interessante sull’implementazione di questa fea-
utilizza le collection - il codice client - in qualche modo si è ture è che praticamente il compilatore non fa altro che
spostata nel codice delle classi server. Anzi, a dir la verità, utilizzare Object e fare il cast al posto vostro, mentre la VM
il totale di complessità in qualche modo è aumentato... non sa neanche dell’esistenza dei generics! Questa tecnica
ma andiamo a vedere il sorgente di List per capire un po’ si chiama erasure, poiché il compilatore cancella tutte le
meglio: informazioni di tipo dalle classi genericizzate, cosicché
List<String> di fatto diventa List, <E> diventa Object, e
public interface List<E> extends Collection<E> { così via. Infarcendo il bytecode con un po’ di cast, il gioco
// ... è fatto.
boolean add(E o); Questa scelta implementativa, che è stata necessaria per
E get(int index); non stravolgere le VM esistenti, porta con sé però diversi
// ... problemi, e ci sono molte situazioni in cui capire esatta-
} mente cosa succede, non è per nulla semplice, anche per
i più esperti.
La prima cosa che salta all’occhio è che List ora è diventato
List<E>, leggasi una lista di E. E rappresenta il tipo di ele-
mento che può essere gestito da List, ed è un tipo generico. Type Variable Significato
E si chiama Type Parameter o Type Variable, ed è l’iniziale
E Element
di Element, ed anche se si può usare qualsiasi lettera al
suo posto è una scelta piuttosto comune. Si dirà: ma non K Key
bastava Object? Cosa è cambiato? V Value
È cambiato che per costruire un oggetto List ora si può dire T Type
al compilatore quale tipo deve sostituire al posto di E, e da
quel momento in poi l’oggetto sarà una lista di String, come TABELLA 2
nell’esempio di prima, e non più una lista qualsiasi. Nota: è
ovviamente possibile e perfettamente legale istanziare una
List non parametrizzata, altrimenti tutto il codice pre Java5 L’argomento è molto vasto (troppo?) e non si esaurisce
diventerebbe di colpo illegale! certo in queste poche righe: argomenti come i bounded
Per capire meglio, immaginate che il tipo sia un parametro type, i generic nested types, gli wildcard, il subtyping ed
da passare ad un metodo,: altri hanno bisogno di un certo sforzo di apprendimento e
di un po’ di pratica per essere padroneggiati, senza contare
• List<E> è una dichiarazione generica di tipo, equivalen- gli angoli oscuri a cui abbiamo appena accennato. Quello
te al nome di un metodo che abbiamo visto è l’assoluto minimo che bisogna sapere
• E è il parametro di tipo, equivalente al tipo del parametro sui generics per non cadere dalle nuvole di fronte a del
di un metodo codice Java5!
• List<String> fornisce un argomento al tipo, in questo
caso String, equivalente all’effettivo valore del parametro Nuovo ciclo for (enhanced for)
nella chiamata di un metodo
Questo nuovo costrutto, insieme ai generics, è quello sicu-
La prima lezione da imparare sui tipi generici è quindi che ramente più invasivo: volente o nolente, prima o poi con
List<String> e List<StringBuilder> non sono due differenti Java5 vi troverete ad usare la nuova sintassi e ad apprez-
classi, ma semplicemente due diverse istanze della stessa zarne le qualità. Niente di trascendentale, ma sicuramente
classe a cui è stato passato un diverso tipo come parame- una maggiore sinteticità e leggibilità, soprattutto quando
tro. combinato con i generics.
Questo può apparire contro intuitivo perché siamo abituati Dal punto di vista teorico, esistono due tipi di iteratori,
a considerare tutto ciò che è a sinistra dell’identificatore esterni ed interni (Booch li definisce attivi e passivi, rispet-
in una dichiarazione come il suo tipo: la difficoltà è che to al ruolo che ha il client). Un iteratore è chiamato esterno
bisogna imparare a leggere le parentesi angolari come se quando è il client che ha il controllo del suo avanzamento
fossero le parentesi tonde di un metodo, e ricordarsi che (attivo), mentre uno interno (passivo) controlla da sé l’ite-
con Java5 è possibile parametrizzare una classe passando- razione. Gli iteratori “classici” di Java sono esterni: tipica-
gli dei valori. In questo modo la classe sarà più specifica, e mente un iteratore esterno offre una maggior flessibilità
funzionerà solo con quel determinato tipo che gli è stato di uno interno poiché si ha un controllo più fine sull’itera-
passato in fase di dichiarazione: l’oggetto people dell’esem- zione, ed in effetti ci sono dei problemi difficili da risolvere
pio è una Collection che accetta solamente Stringhe e non solamente con iteratori interni: basti pensare al confronto
più oggetti qualsiasi. degli elementi di due liste per rendersene conto.
Questa lezione è di fondamentale importanza: c’è una sola È però vero che l’iteratore interno è molto più conciso ed
classe, indipendentemente dal numero di parametri di elegante nella stragrande maggioranza dei casi! E basta un
tipo, e questo limita fortemente cosa si può e cosa non si esempio per rendersene conto.
e i corrispettivi wrapper Il secondo ciclo è circa 20 volte più lento, questo per via
di tutte le conversioni automatiche (sia boxing che unbo-
xing) che vengono eseguite ad ogni iterazione.
Ovviamente non ci si limita ai tipi numerici, ed ora potrete
anche scrivere:
Integer i = 0;
Boolean vero = true;
Dietro le quinte, il compilatore si occupa delle necessa- Boolean expression = exp1 && exp2 || exp3
rie conversioni fra tipo base ed oggetto, che da sempre
tormentano i programmatori Java. Questa conversione Un ultimo dettaglio: il boxing/unboxing non avviene per la
da tipo primitivo ad oggetto wrapper è chiamata boxing risoluzione di metodi in overload, ma continuano a valere
e, visto che succede in automatico, la feature è chiamata le regole pre-Java 1.5. Questo per non variare il compor-
autoboxing, mentre l’operazione opposta - da oggetto tamento di programmi compilati per versioni precedenti.
wrapper a tipo primitivo - è chiamata unboxing (senza Considerate infatti cosa accadrebbe se il boxing fosse ap-
auto, chissà perché). plicato in una situazione simile:
Ovviamente questo semplice esempio non rende l’idea, ma
// ...
public void doSomething(double num); sere un sottotipo o un supertipo. Per un linguaggio object
public void doSomething(Integer num); oriented, se sia meglio avere tipi covarianti o controvarian-
ti è una scelta di design che è ancora argomento teorico di
//... dibattito: noi ce ne terremo lontani (Tabella 3).
int x = 1; Possiamo avere invarianza, covarianza o controvarianza
doSomething(1); per i tipi di ritorno di un metodo, per i suoi parametri, o
per le eccezioni che lancia.
Per Java 1.4, verrebbe invocato il primo metodo, mentre
per Java 1.5 verrebbe invocato il secondo per via
dell’autoboxing!
Tipo Relazione con il
supertipo
Static import Invarianza Non cambia
Covarianza Può essere un sottotipo
Lo static import è fortunatamente una delle novità più
semplici da imparare.
TABELLA 3
Questa novità permette semplicemente di “importare”
variabili e metodi statici, in modo da poterli eseguire
direttamente senza il nome della classe. Anche questa Un esempio di covarianza pre-Java5 sono le eccezioni:
quindi è una feature più di forma che di sostanza, e serve l’override di un metodo che lanci eccezioni è tenuto
per risparmiare qualche carattere e scrivere codice più a lanciare eccezioni in maniera covariante: le stesse,
leggibile: o dei sottotipi, A voler essere precisi può anche non
lanciarne nessuna (ma così mi si rovina l’esempio): co-
import static java.lang.System.out; munque, se il metodo lancia eccezioni, queste devono
// ... essere covarianti.
out.println(“Hello, world!”); Discorso diverso invece per i parametri di un metodo, che
sono invarianti: scrivere questo codice
ma anche
public class Base {
import static java.lang.Math.*; public void uno(CharSequence sequence) {
import static java.lang.System.out; System.out.println(“Base.print “ + sequence);
// ... }
out.println(PI); }
Covarianza (sul tipo di ritorno) porta in realtà ad un overload e non certo ad un override.
Per accertarsene, basta verificare l’output del main: viene
La covarianza sul tipo di ritorno è un altro aspetto di Java5 eseguito il metodo della classe base e non della classe de-
passato un po’ in sordina. In realtà il suo inserimento in rivata
Java5 è stato accessorio all’inserimento di altre feature, ma Ritornando alle novità di Java5, è ora possibile avere il
è comunque una caratteristica in più ed utile di per sé, so- tipo di ritorno covariante e dunque scrivere codice come
prattutto perché può semplificare il design in diversi casi. questo (mi si perdoni il dominio dell’esempio, che è pa-
Qui c’è sicuramente bisogno di un appoggio teorico, anche tetico):
per chiarire alcuni aspetti che spesso non vengono chiariti
abbastanza. Troppo spesso si legge che Java5 supporta la public abstract class Erbivoro {
covarianza, in realtà con Java5 ora c’è il supporto della co- public abstract Erba mangia();
varianza sul tipo di ritorno, poichè alcune caratteristiche del }
linguaggio erano già covarianti da tempo immemore. public abstract class Cavallo extends Erbivoro {
Ma vediamo le definizioni: public abstract Fieno mangia();
Un tipo, relativamente al suo supertipo, può essere inva- }
riante, covariante o controvariante. Invariante vuol dire
evidentemente che deve essere lo stesso. Covariante e Dove Fieno estende Erba, permettendo dunque ad una
controvariante vogliono dire, rispettivamente, che può es- sottoclasse di specificare meglio il comportamento rispetto
I
di programmazione, nato oramai più di 10 anni fa.
Ai tempi della sua gestazione, uno dei linguaggi di
niziamo il nostro corso spiegando alcuni con- programmazione più usati era il linguaggio C, mentre
cetti base. Il nome “Java” è un nome che rac- il suo designato successore era il linguaggio C++. Il
chiude in sé le diverse tecnologie che com- C++ è una estensione del linguaggio C che mantie-
pongono la “piattaforma” Java. In particola- ne la compatibilità all’indietro: cioè ogni programma
re, Java è innanzitutto un (bel) linguaggio di scritto in C è, a meno di marginali modifiche, utiliz-
programmazione, ed è quello che la maggior zabile come programma C++.
parte dei neo-programmatori Java desidera
imparare. Java però è anche il nome della “virtual Raccontano le cronache che James Gosling, il prin-
machine”, ovvero l’ambiente di l’esecuzione di pro- cipale autore del linguaggio Java, aveva tentato di
grammi, nota più propriamente con l’acronimo JVM usare il C++ per realizzare un editor per l’SGML
(ovvero Java Virtual Machine). La JVM è il più usato (il precursore dell’attuale XML), ma si era scontrato
(ma non l’unico) ambiente di esecuzione per i pro- con la sua grande complessità. Notoriamente il C++
grammi scritti in linguaggio Java. presenta non poche difficoltà: queste sono indotte
anche dal fatto che è un linguaggio sostanzialmente
Infine, sotto il nome di Java ricadono anche le ampie di basso livello; si tratta di una caratteristica eredita-
e complesse librerie standard della “piattaforma” ta dal fatto che è volutamente compatibile con il C.
Java; queste librerie fanno sì che essa sia qualcosa Questo fatto, aggiunto alla grande quantità di “featu-
di più di un linguaggio di programmazione: ovvero re” (funzionalità) disponibili, lo rende un linguaggio
Java è un completo ambiente di esecuzione di pro- molto difficile, che richiede grande accortezza nella
grammi che isola dal sistema operativo sottostante. stesura dei programmi, e presenta tanti trabocchetti
Per questo motivo si parla di piattaforma: non si per i programmatori.
tratta di un vero e proprio sistema operativo (non
arriva a mettere le radici nell’hardware, fornendo Quando Gosling si trovò a dover scegliere (o pro-
device driver e cose del genere), ma è completamen- gettare) un linguaggio di programmazione per una
te autosufficiente per quanto riguarda lo sviluppo nuova applicazione, pensò di partire dal C++ proprio
di software. Una volta scritto un programma in perché veniva considerato “il linguaggio del futuro”.
Java, per eseguirlo basta il cosiddetto Java RunTime Sun stava infatti sviluppando un sistema di nuova
Environment, che esiste per numerosi sistemi ope- concezione (quello che poi, dopo varie peripezie, sa-
rativi: Windows, Linux, Solaris, MacOSX, AS/400 e rebbe diventata la piattaforma Java), e Gosling creò
così via. un linguaggio chiamato Oak (in inglese ‘quercia’, che
richiama l’idea della solidità e robustezza). L’idea di
Il linguaggio Java fondo era quella di riprendere la sintassi e le migliori
idee del C++, ma, al prezzo di “rompere con il passato”
Esaminiamo le caratteristiche specifiche del linguag- (ovvero la compatibilità con il C), creare un derivato
gio Java e la sua genesi. Si tratta di un linguaggio con una sintassi e una semantica simile, ma molto
più semplice, lineare, coerente, facile da imparare e che white-paper di molti anni fa su Java 1.0 in cui si ripeteva il
presentasse meno trappole per i programmatori. mantra: less is more (meno è di più).
In effetti, chi conosce il C++ e Java si rende conto che Praticamente sono state rimosse tutte le caratteristiche
molti concetti sono gli stessi: si ha la stessa sintassi di base, che rendevano difficile la lettura del codice (come l’opera-
ereditata dal C; il modo di definire classi e oggetti in Java è tor overloading, che permette di dare agli operatori come
abbastanza simile a quella del C++ (anche se decisamente il “+” significati diversi, ma costringe il programmatore a
meno potente). Infatti esaminando in dettaglio si scopre fare molta attenzione al tipo di una variabile). Sono state
che molte caratteristiche del C++ sono state rimosse. È come se anche rimosse alcune parti che complicavano parecchio
qualcuno avesse voluto usare un sottoinsieme del C++ in- l’implementazione (per esempio l’ereditarietà multipla).
serendo solo quello che era strettamente utile. Ricordo un Altre caratteristiche del C++ sono rimaste a lungo fuori
dal linguaggio Java ma sono state poi reintrodotte solo di
recente (come la programmazione generica). In definitiva
Java vuole essere un C++ più semplice e lineare. Ma non
si è trattato solo di pulire la sintassi: Java ha anche intro-
dotto nuove funzionalità, come l’esecuzione su una virtual
machine e la “garbage collection”.
Chi conosce
C++ e Java si rende
conto che molti concetti
sono analoghi
La Garbage Collection
Per capire come funziona la garbage collection possiamo I programmi scritti in Java possono essere eseguiti in vari
fare riferimento alla Figura 1: ho rappresentato schema- modi. Se pensate al C, sapete che i programmi vengono
ticamente una situazione tipica di un programma Java in compilati in codice nativo, per poi essere eseguiti diret-
esecuzione. Il programma utilizza la memoria a partire tamente dal processore (il C e il C++ è solitamente un
dalle sue variabili. Tutte le variabili attualmente in uso si compilatore puro). Se pensate al Basic (o al JavaScript
trovano in un posto noto, chiamato “stack”. Tutta la me- per considerare un altro caso più recente), sapete che i
moria usata dal programma è accessibile solo attraverso le programmi possono venire eseguiti così come sono, senza
variabili in uso, che fanno riferimento all’area di memoria nessun passo intermedio. Si tratta della tradizionale di-
di uso dinamico chiamata “heap”. Nello heap sono “allo- stinzione tra interprete e compilatore (che nel caso di Java
non vale del tutto).
Compiled from “Hello.java”
Va subito detto che per Java esistono
public class Hello extends java.lang.Object{
sia compilatori puri che interpreti puri.
public Hello();
Esiste per esempio il compilatore GCJ,
Code:
che trasforma un programma Java in
0: aload_0
codice nativo, eseguito direttamente dal
//Method java/lang/Object.”<init>”:()V
processore. Esistono anche interpreti puri
1: invokespecial #1;
(come la BeanShell), in grado di esegui-
4: return
re programmi Java direttamente, così
come sono, senza alcuna trasformazione
public static void main(java.lang.String[]);
intermedia. Nella maggior parte dei casi
Code:
tuttavia, Java viene utilizzato seguendo
//Field java/lang/System.out:Ljava/io/PrintStream;
l’approccio originale: ovvero viene prima
0: getstatic #2;
compilato in un codice intermedio, detto
3: ldc #3; //String Hello, world
bytecode, e poi eseguito da un interprete,
//Method java/io/PrintStream.println:(Ljava/lang/String;)V
detto Java Virtual Machine. Questo fa
5: invokevirtual #4;
di Java un linguaggio essenzialmente
8: return
interpretato; tuttavia quello che viene
interpretato non è il codice Java così come
}
è, ma un suo codice intermedio, risultante
da compilazione esplicita, detto bytecode.
LISTATO 3 II bytecode di Hello
Siete alle prime armi e non sapete da dove scaricare Java? Allora prima di cominciare a leggere l’articolo leggete
queste istruzioni.
Java viene fornito con due diversi download: il Java Runtime Environment (JRE), e il Java Development Kit (JDK).
Il primo (JRE) serve per eseguire programmi in Java, mentre il secondo (JDK) serve per SVILUPPARE programmi in
Java. Poiché vogliamo programmare, è necessario procurarci il JDK. Consigliamo di usare l’ultima versione, la 5.0.
Potete scaricare il JDK dal sito http://java.sun.com. Fare attenzione che sito http://www.java.com fornisce il JRE, non
il JDK. La posizione del JDK è, al momento in cui scrivo, questa (ma può ovviamente variare in quanto i rilasci di
nuove versioni si susseguono con un ritmo frenetico):
http://java.sun.com/j2se/1.5.0/download.jsp
Consiglio per il momento di scaricare solamente il JDK, e non il bundle che comprende anche l’ambiente di program-
mazione NetBeans: può essere abbastanza complicato orientarsi con un ambiente di sviluppo tuttofare finché non si
conoscono i fondamenti. Gli esempi del nostro corso possono essere provati per il momento con un semplice editor di
testo (ad esempio, Notepad su Windows).
Ricordatevi comunque, dopo aver installato il JDK, di aggiungere al PATH gli strumenti di sviluppo. Se state usando
Windows, dovete andare nel pannello di controllo, scegliere Sistema, Avanzate e poi Variabili di Ambiente, e infine
impostare la variabile PATH e aggiungere all’inizio “C:\Programmi\Java\jdk1.5.xxx\bin;” (cambiare xxx con l’effettiva
versione che avete nel vostro computer). A questo punto, da una finestra terminale, digitate “java -version”. Se leg-
gete la versione di Java siete pronti per lavorare.
Proviamo adesso a toccare con mano queste caratteri- ni. Ma se utilizziamo il comando javap -c Hello possiamo
stiche, partendo dal nostro primo listato, mostrato nel decodificare il bytecode ottenendo quello che vediamo nel
Listato 2. Sfortunatamente, in Java anche il classico Listato 3.
programma che stampa al terminale “Hello World”, usa
molti concetti che non sono ovvi: occorre necessaria- Cosa scopriamo pertanto? Che il bytecode assomiglia mol-
mente creare una classe, citare concetti avanzati come to ad un vero assemby. In effetti la JVM assomiglia molto
gli array, imporre la visibilità pubblica, chiamare un meto- ad un vero processore, solo che non è realizzato in silicio
do e un campo statico. Tutti concetti che approfondiremo ma direttamente in software. C’è da dire comunque che
strada facendo. Per il momento non consideriamo perché la JVM non è esattamente progettata come un processore
il listato è scritto così, ci concentriamo su come fare ad fisico, e presenta alcuni concetti “evoluti” come l’invoca-
eseguire il nostro primo programma, con lo scopo di zione di metodi virtuali e altre caratteristiche che rendono
esplorare il meccanismo di esecuzione e la Java Virtual particolarmente semplice compilare per essa un linguaggio
Machine. di alto livello (come Java).
non significa che non ci sia un degrado di prestazioni “write once run anywhere”. In realtà il raggiungimento
rispetto al codice macchina puro; significa che il degra- effettivo di questo obiettivo ha richiesto considerevoli
do di prestazioni è molto inferiore a quello che normal- sforzi, ma si può dire che, dopo anni di sviluppo, sia stato
mente si pensa. In alcuni casi, la velocità di esecuzione raggiunto, e non solo in teoria ma anche in pratica.
di un interprete Java può essere addirittura superiore
a quella di codice equivalente scritto in C/C++, perché La libreria di Java, inizialmente piccola e semplice (con la
il compilatore Just-In-Time è in grado di ottimizzare versione 1.0 di Java) si è nel tempo ingrandita in maniera
il codice durante l’esecuzione, in base ai risultati delle considerevole. In effetti il “nocciolo” della piattaforma
esecuzioni precedenti! Java, la sua portabilità, è legata al fatto che è possibile fare
moltissime cose utilizzando solamente la libreria standard
In verità, Java viene usato spesso per compiti abbastanza di Java. In questo modo un programma dipende solo da
complessi: viene utilizzato spesso per realizzare appli- essa; a sua volta la libreria Java è stata adattata a gran
cazioni di tipo Web, che operano su complessi database parte dei sistemi operativi moderni attualmente in uso
relazionali. In questi casi, il tempo che viene impiegato per (Windows, MacOSX, Linux, Solaris, AS/400 eccetera);
la trasmissione in rete delle pagine Web o per accedere al in questo modo un programma “in Java” può funzionare
database occupa una porzione di tempo molto significativa praticamente dovunque senza modifiche.
(in certi casi superiore al 99%) rispetto al puro tempo di
esecuzione del codice Java. In questi ambiti la pura veloci-
tà di esecuzione del linguaggio conta molto poco rispetto
al contesto. Infatti vengono comunemente utilizzati per
questo tipo di applicazioni anche linguaggi di scripting,
che sono, nei fatti, molto più lenti di Java, e raramente
La libreria Java è
si considera la loro “pura” velocità di esecuzione come un
fattore determinante.
indipendente dal
Ma Java viene anche utilizzato anche per costruire i cosid-
sistema operativo
detti “Application Server”, ovvero complesse infrastrutture
per l’esecuzione di programmi, dei veri e propri “sistemi sottostante
operativi” per lo sviluppo di applicazioni Web. Siccome
Java è nei fatti piuttosto efficiente e veloce, è possibile
realizzarli interamente in Java.
In realtà, un programma scritto male può dipendere da
La libreria di Java comportamenti del sistema operativo sottostante, e quindi
comportarsi diversamente su sistemi operativi differenti.
Abbiamo dunque visto che abbiamo a che fare con un buon Nel corso degli anni però questo problema si è via via at-
linguaggio di programmazione, e un buon supporto a tempo tenuato, anche se ricorrendo a dei compromessi, a volte
di esecuzione dello stesso, la JVM. Ma tutto questo non fa eccessivi. La libreria di Java si è da un lato ingrandita (ver-
(ancora) di Java una piattaforma. I linguaggi di program- so l’impresa), dall’altro ridotta (verso i dispositivi mobili).
mazione tradizionali, come il C, il Pascal o lo stesso C++, Per questo motivo la “piattaforma Java” è stata divisa in
prevedono nello standard le sole librerie standard minime tre edizioni: Standard, Micro ed Enterprise. Di fatto la
per fare input/output a riga di comando. Il C++ va un po’ differenza tra queste edizioni consiste, oltre a una virtual
avanti perché fornisce anche, nelle sue versioni più recenti, machine diversa per la Micro Edition, in un diverso corre-
strutture dati e algoritmi standard. Ma linguaggi più recenti do di librerie fornite.
come Visual Basic o Delphi, forniscono anche tutto il ne-
cessario per sviluppare applicazioni a interfaccia grafica con La Standard Edition è quella che abbiamo quando scari-
connessioni a database: ovvero forniscono allo sviluppatore chiamo Java dal sito http://java.sun.com. Per essere cor-
professionista il necessario per sviluppare applicazioni senza retti, sul sito Sun sono disponibili due diversi pacchetti: il
dover ricorrere a ulteriori componenti di terze parti. Runtime Environment e il Development Kit. Il primo serve
per l’esecuzione di programmi in java; è il minimo assoluto
Il Java standard fornisce, insieme al linguaggio di pro- necessario per poter usare programmi in Java sul proprio
grammazione e alla virtual machine, anche una cospicua computer. Il secondo invece comprende degli strumenti
libreria che permette di fare tutte le principali attività per lo sviluppo, in particolare il compilatore e altre utilità
necessarie per lo sviluppo di programmi di tipo Desktop: per la programmazione.
creazione di interfacce grafiche, accesso a database, ma
anche librerie per la manipolazione di strutture dati, di La Micro Edition è Java adattato per funzionare su pal-
immagini, per processare l’XML, accedere al web e molto mari, cellulari e in generale su dispositivi meno potenti di
molto altro. Il bello della libreria Java è che, come la virtual un Desktop Computer. In un certo senso, si tratta di una
machine, è totalmente indipendente dal sistema operativo versione ridotta della Standard Edition; comprende anche
sottostante. Questo fa sì che un programma scritto in Java librerie specifiche per funzionalità dei dispositivi mobili
sotto Windows possa funzionare senza modifiche anche che non sono presenti nella Standard Edition.
sotto Linux e il Mac. Questa è la grande promessa di Java: Di solito, troviamo Java già pronto per eseguire applica-
zioni in molti dispositivi mobili, come i telefoni cellulari Gli elementi base di un programma in Java sono costanti
Nokia, Motorola o SonyEriccson (per citare solo i casi più e variabili. Una costante è per esempio il numero uno (1),
noti). Esistono anche versioni che si scaricano e si instal- un carattere ‘a’, o una stringa “hello”. Ci sono dei dettagli
lano, come la J9 di IBM disponibile per dispositivi PalmOS che vedremo più avanti. Una variabile è invece una se-
e PocketPC. La Micro Edition tuttavia è meno incapsulata quenza alfanumerica di lettere o numeri: per esempio a
della Standard Edition, anzi è piuttosto modulare (molti è una variabile. Per la verità anche _1 o a$ sono variabili
dicono troppo): esistono infatti diversi profili e configura- valide in Java: la regola per gli “identificatori” è che siano
zioni. Per i dettagli rimandiamo all’articolo sull’argomento sequenze alfanumeriche di lettere, numeri, il carattere “_”
su questo stesso numero. o il carattere “$”, e non possono cominciare con un nume-
ro. In realtà Java permette anche di usare caratteri come le
La Enterprise Edition invece è la Standard Edition estesa lettere accentate come lettere. Usando variabili, costanti e
con una serie di funzioni che sono utili per la realizzazio- operatori (+,-,* eccetera) si creano delle espressioni. Quindi
ne di applicazioni complesse per le imprese, di solito con nel caso più semplice avremo:
interfaccia Web, ma che comprendono una serie di compo-
nenti distribuiti che si parlano tra di loro. Di solito per ave- a+1
re la Enterprise Edition occorre procurarsi un applicativo
che la implementa, comunemente noto come Application Notare che in Java (come in C o in JavaScript) l’assegna-
Server. Per esempio sono application server generalmente mento (=) è un operatore. Si possono anche usare le paren-
conformi a una versione di Java Enterprise Edition prodot- tesi, quindi la seguente è una espressione:
ti commerciali come BEA WebLogic o IBM WebSphere, o
prodotti Open Source come JBoss o Apache Geronimo. Ma b = a + (c-1)
approfondiremo l’argomento in dettaglio in queste pagine
prossimamente. Fin qui abbiamo considerato il mattone fondamentale di
Java; ma un programma in Java non è solo un calcolo, ma
una sequenza di calcoli. Chiameremo comando un singolo
un applicativo che la b = a + 1 ;
int doubler(int x) {
corre sempre dichiararla, ovvero specificare il suo tipo. Una int res = x*two;
dichiarazione può anche essere seguita da una espressione return res;
di inizializzazione (e conclusa da un punto e virgola) }
}
int a = 1;
L’esempio non vuole essere codice da usare in programmi
Una dichiarazione può essere usata (senza inizializzazio- reali. È scritto in questo modo per evidenziare due cose: le
ne) quando viene dichiarato un metodo, come nel seguente diverse posizioni in cui è possibile collocare una dichiara-
caso: zione di variabile, e le cosiddette variabili libere. Ma andia-
mo con ordine.
int sum(int a, int b) {
return a+b;
} Per prima cosa notiamo la dichiarazione di variabile: oltre
ad essere presente nel parametro del metodo (int x), è pre-
I metodi in Java assomigliano alle funzioni o alle proce- sente anche dentro il metodo (int res = x * two) e fuori dal
dure di altri linguaggi di programmazione. Questa strut- metodo ma dentro la classe (int two=2). Nel primo caso,
tura già diventa più complicata. Abbiamo l’intestazione la variabile viene comunemente chiamata variabile locale.
int sum(int a, int b). In gergo si dice che è la “firma” di Il motivo è che queste variabili vengono create quando
un metodo. Indica cosa viene fornito in ingresso e cosa si entra nel metodo, ma scompaiono quando si esce dal
viene ritornato quando viene chiamato. Un metodo in un metodo. Nel secondo caso (int two=2) queste variabili ven-
certo senso assomiglia ad una funzione matematica, ma in gono chiamate campi, e sono persistenti. Per essere esatti
realtà è qualcosa in più. La firma dichiara i parametri che (ma è un concetto che dovremo riesaminare più avanti in
prende e il valore che ritorna: il metodo add dunque pren- maggior dettaglio) i campi esistono fin tanto che esiste
de due parametri a e b di tipo intero, e ritorna un risultato l’oggetto che le contiene.
intero. Dopo la firma abbiamo il corpo del metodo, ovvero
una sequenza di comandi racchiusi tra parentesi graffe. Infine introduciamo il concetto di “variabile libera”. Se
In alcuni casi ci serve solo la firma, e non il corpo: in osserviamo in dettaglio il corpo del metodo doubler no-
questi casi al posto del corpo c’è semplicemente un punto teremo a un certo punto l’espressione res = x*two. Ora,
e virgola. res è una variabile locale, mentre x è un parametro, ma
two non è nessuna delle due. Guardando il solo corpo
Un elemento importante è che i metodi non possono es- del metodo non si riesce a trovare dove questa variabile
sere dichiarati da soli. In altri linguaggi è possibile avere è dichiarata: per questo motivo viene detta variabile li-
una funzione sum, ed è un componente non collegato ad bera. Ma in Java le variabili libere di un metodo possono
altro in un programma. Non così in Java: non abbiamo solo fare riferimento alle variabili della classe, ovvero ai
un concetto di funzione a sé stante, ma solo di metodo, e campi.
come tale deve trovarsi sempre dentro la dichiarazione di
una classe. È abbastanza importante sviluppare occhio per le variabili
libere in un metodo: questo ci permette di localizzare fa-
Come abbiamo detto, una classe è la minima entità auto- cilmente i campi; è dove vengono memorizzate le informa-
noma in java: zioni che devono persistere al di fuori del metodo corrente.
In un certo senso, le variabili libere mettono in comunica-
class Hello { zione il metodo con la classe che le contiene.
}
Conclusioni
è un programma valido che può essere compilato da solo.
Ma non fa assolutamente nulla. Dentro la classe possiamo Se Java lo conoscevate solo per sentito dire, adesso ab-
inserire la dichiarazione di un metodo: biamo mosso i primi passi. Abbiamo parlato di virtual
machine e di byte code, e abbiamo spiegato le varie edi-
class Sum { zioni di Java. Nel prossimo numero vedremo in dettaglio il
int sum(int a, int b) { linguaggio, esaminando come sono implementati in Java i
return a+b; classici costrutti di programmazione.
}
}
Note Biografiche
Anche questa è una classe valida, e contiene anche un me- Michele Sciabarrà si occupa di Java fin da quando, nel 93, sca-
todo di somma. Per completare il discorso, ci serve capire ricò il sorgente di HotJava e per compilarlo saturò il disco del-
la Workstation Sun che amministrava. Da allora ha lavorato in
che relazione abbiamo tra un metodo e una classe. Consi- Java passando dalle applet per Netscape 2 fino alle applicazioni
deriamo questo esempio: bancarie di classe enterprise. Dopo aver scritto di Java e averlo
insegnato per dieci anni, è direttore esecutivo di Java Journal.
Quando non cerca di imparare le ultime API o disquisisce della
class Doubler { superiorità del modello Open Source, si diletta a programmare
int two =2; cellulari Symbian in C++ e a amministrare sistemi Linux.
if (a instanceof b) {
La massima di questo mese: “My guess is that // fai qualcosa
} else if (a instanceof c) {
object-oriented programming will be in the 1980s // fai qualche altra cosa
what structured programming was in the 1970s. }
Everyone will be in favor of it. Every manufacturer
Ora, già l’uso di instanceof è di per sé criticabile:
will promote his products as supporting it. Every
instanceof in un linguaggio ad oggetti non dovreb-
manager will pay lip service to it. Every program- be mai essere usato, se non in un caso particolare
mer will practice it (differently). And no one will che lascio come simpatico esercizio agli amici let-
know just what it is.” tori.
T. Rentsch
Ma usare instanceof per fare eseguire logiche di-
verse ad un oggetto a seconda del suo tipo, è vera-
mente abominevole: a cosa serve il polimorfismo
– che fa esattamente la stessa cosa - se poi devo
ricostruirmelo malamente da solo? Notare che il
#1: Il polimorfismo dei poveri fatto che l’operazione sia eseguita sullo lo stesso
oggetto su cui si è operata la condizione o su un
Voglio cominciare questa rubrica con una “worst altro è irrilevante: in quest’ultimo caso è solo se-
practice” fra le più orribili, il polimorfismo dei gno di un cattivo assegnamento di responsabilità
poveri. Non che non abbia materiale a disposizio- e della necessità di spostare l’eventuale metodo al
ne per decine e decine di rubriche, e centinaia di posto giusto.
esempi di come non si dovrebbe scrivere del codice
in Java... ma questa particolare pratica, oltre a es- a.faiQualcosa()
sere veramente brutta, ha delle caratteristiche che
secondo me la rendono unica. E per questo deve È evidente come il vero polimorfismo sia infinita-
avere l’onore del primo numero di questa rubrica mente superiore alla sua brutta copia: l’”if ” viene
dedicata alle brutture nel design. fatto dal runtime automaticamente, e voi non
dovete fare nulla di particolare se non usare degli
• È assolutamente non necessaria, e l’alternativa è oggetti in maniera polimorfa. Il polimorfismo dei
nell’abc della programmazione ad oggetti poveri invece va invece mantenuto, ogni volta che
• Non offre nessun vantaggio particolare rispetto si introducono nuovi tipi e nuove logiche: di solito
all’alternativa corretta, ma solo svantaggi. Altre fra l’altro questo tipo di strutture condizionali si
brutture perlomeno hanno una qualche giustifi- trovano ripetute in diversi punti del codice, poi-
cazione più o meno fondata, questa no. chè è molto comune che esistano diverse logiche
• È incredibilmente diffusa da eseguire, rendendo l’introduzione di bug così
probabile da essere quasi scontata. Il vero poli-
Il polimorfismo dei poveri è caratterizzato da codi- morfismo invece vi permette semplicemente di
ce simile a questo: aggiungere nuovi metodi per ogni nuova logica,
concentrando così in unico punto tutto ciò che ha
Eseguite per curiosità un bel Eliminare il polimorfismo dei poveri da uno qual-
siasi degli esempi Swing del jdk. Come dite? Eh no,
grep -R instanceof . così bisogna rivedere le gerarchie... e poi inserire
nuove interfacce. E poi bisogna eliminare quelle
nella directory demo del vostro JDK, e troverete istanziazioni di oggetti concreti... bene, quella si
molti esempi di poliformismo dei poveri. Sembra chiama programmazione ad oggetti.
che Swing sia un portatore (sano?) di polimorfi- Ora salutate con la manina quella brutta e vecchia
smo dei poveri! programmazione strutturata, e cercate di lasciar-
vela per sempre alle spalle!
JJ: Ciao Daniela, ci racconti che cosa è il JIA e da JJ: Dalla tua posizione di osservatore privilegia-
quando tempo esiste? to, come ti sembra sia cambiato il mondo Java in
questi anni?
DR: la Java Italian Association è nata l’11/12/1997 da-
vanti ad un notaio di Roma grazie alla volontà di un DR: Moltissimo. Ho assistito a cambiamenti radicali su
gruppo di amanti della tecnologia java. Questa associa- questa tecnologia e visto nascere il mondo opensource
zione senza scopo di lucro, costituita da 66 soci fondato- che ben si integra con esso.Ho visto la proliferazione di
ri, è un punto di riferimento sia per il mondo del lavoro un gran numero di prodotti di ogni genere e qualità, di
che per quello della scuola. Tramite JIA è possibile per i framework che permettono di risparmiare tempo: sono
soci anche ottenere una visibilità maggiore, promoven- basati su scheletri gestiti da elementi descrittivi spesso
do la loro professionalità attraverso la docenza in corsi o di tipo xml, a partire dei quali è possibile generare codi-
seminari java, o nella scrittura di articoli o in altre occu- ce e costruire per esempio interi portali.
pazioni sociali e culturali utili alla comunità Java. Nello Tuttavia non sono completamente favorevole ai fra-
statuto sono descritte in dettaglio tutte le attività di cui mework perché se da una parte permettono di generare
ci JIA si può occupare. un prodotto con meno errori perché si deve intervenire
meno nel codice, spesso per imparare ad usarli occor-
re un tempo superiore alla vita del framework stesso.
JJ: Quali sono le attività più interessanti che ri- Inoltre sono spesso invasivi nel codice e, a causa del
cordi del JIA in questi anni? livello più alto di astrazione, non sono facili da gestire
se qualcosa non funziona, o se si devono effettuare delle
DR: Ne abbiamo fatte veramente tante: la produzione personalizzazioni pesanti.
di CD, la partecipazione a seminari a conferenze im-
portanti, la traduzione di corsi java dall’inglese... Direi JJ: Come sono i rapporti con i vari Java User
che il progetto più interessante è stato il progetto scuola Group?
diretto a docenti e studenti di scuola media e realizzato
assieme alla società Sun Microsystems e al Ministero DR: C’è stata un po’ di diffidenza iniziale e qualche
dell’Istruzione, Università e Ricerca nel 2003. Adesso, incomprensione. Ma confido in un futuro denso di col-
nel 2006, siamo in partenza con la seconda release. laborazioni anche perché abbiamo un obiettivo comune
Nel 2003 Il progetto comprendeva tre corsi web in che è la divulgazione di Java e non avrebbe molto senso
lingua inglese fornito dalla società Sun Microsytems fare una guerra tra “fratelli” perché sarebbe contropro-
mentre JIA forniva i tutor di supporto ai docenti sui ducente per tutti. Inoltre non vedo JIA in contrapposi-
corsi java. Il progetto ha previsto anche la realizzazione zione con i JUG. JIA non è un JUG perché porta avanti
di un mini-portale, che è partito il 15 Gennaio con la temi sociali che siano utili a tutti, anche verso le cate-
pre-registrazione degli studenti e degli insegnanti dopo gorie meno esperte e disagiate. I JUG invece possono
un incontro con la stampa avvenuto a Milano in data occuparsi di tematiche più avanzate e all’avanguardia.
10/1/2003. La sua durata è stata di circa un anno. Nel Oggi esistono più JUG a livello locale, questo sicura-
2006 invece il progetto riguarda la possibilità di par- mente facilita gli incontri dal vivo e in questo modo si
tecipare ai corsi del programma SAI (Sun Accademic possono creare collaborazioni inter-jug. Questa cosa nel
Initiative della Sun Microsystems). Anche questa volta JIA non si può fare perché essendo una realtà nazionale
JIA fornisce i tutor di supporto ai docenti sui corsi java. ha maggiori difficoltà ad organizzare incontri dal vivo.
RIQUADRO 1 La Java Italian Association caso che sia molto difficile impararla e applicarla nella
maniera adeguata...
La Java Italian Association (http://www.jia.it) è JJ: Cosa vorresti che succedesse nel mondo Java
un’associazione senza scopo di lucro, costituita da 66 nei prossimi anni?
soci fondatori nel 1997 ed è un punto di riferimen- DR: Il futuro dei prossimi anni è del mobile e del voip.
to sia per il mondo del lavoro che per quello della Java è fatto apposta per questi mondi.
scuola. I suoi obiettivi riguardano la divulgazione Ma se nei prossimi anni esplodesse la robotica e la demo-
del linguaggio java e delle tecnologie emergenti con tica sarebbe il massimo poter applicare java anche qui.
ogni mezzo come seminari, articoli e progetti. Tra
le attività più importanti ci sono il progetto “Java JJ: E che cosa temi di più?
a Scuola” organizzato in collaborazione con Sun
Microsystems e con il Ministero dell’Istruzione per la DR: Non esistono linguaggi che un programmatore
formazione java di studenti e docenti di scuola media può temere ma la precarietà del mercato si. Soprattutto
superiore (http://www.jia.it/modules.php?name=C quando in particolare l’Italia ha la concorrenza di paesi
ontent&pa=showpage&pid=93) e “Tecknos” (http: come Cina, Romania, India ecc. dove esistono università
//www.tecknos.it) la conferenza sull’Innovazione anche migliori delle nostre che permettono di preparare
Tecnologica organizzata con la società Apai (http: programmatori molto validi disposti a lavorare a costi
//www.apai.biz) a Sarzana (La Spezia) con lo scopo bassissimi.
di far aumentare il contributo tecnologico italiano in
JJ: Mi racconti un aneddoto divertente che ti è ca-
Europa.
pitato in questi anni come presidente del JIA?