Introduzione
Chiunque
si appresti alla lettura di questo articolo ha, molto probabilmente, un’esperienza
diretta di Java: lo avrà utilizzato per realizzare almeno un applet
o, più probabilmente, un servlet. Qualcuno, poi, potrebbe aver avuto
l’occasione di implementare degli Enterprise JavaBean, degli agenti, o
di sperimentarne le doti di integrabilità in ambienti misti C/C++,
o in congiunzione a linguaggi di scripting come Perl e Python, magari nella
realizzazione di soluzioni server-based. Java, infatti, è un linguaggio
per sua natura multiforme, che ha saputo finora dare il meglio di sé
nella realizzazione di prodotti middleware e nell’implementazione di soluzioni
basate su Web ed Internet, ma comunque e sempre prive di una specifica
interfaccia grafica lato utente: in altre parole, non esiste nessuna killer
application stand-alone realizzata in Java, e chi si è cimentato
nell’impresa – bastino i nomi di Corel ed IBM – ha dovuto ridursi a più
miti consigli.
Si
può discutere se il concetto di killer application mantenga ancora
la sua validità in un mondo basato su applicazioni distribuite e
decentralizzate, o se – addirittura – non possa essere definito come tale
l’intero insieme di soluzioni CORBA/Enterprise JavaBean/Web/XML imperniate
su Java, e che da esso non possono in alcun modo prescindere.
Sta
di fatto, comunque, che il ruolo delle applicazioni stand-alone è,
ed è destinato a rimanere per i prossimi anni, ancora centrale e
ad influenzare fortemente la visione che la più parte delle persone
avrà dell’informatica – specialmente di quella cosiddetta “professionale”
- così come sta di fatto, purtroppo, che in questo mondo il linguaggio
Java è ancora un grande assente.
I
motivi di questa aporia sono, o sono stati, molteplici:
-
L’oggettiva
penalizzazione nelle performance causata dalla pseudo-compilazione dei
programmi Java in una sorta di linguaggio macchina indipendente dalla CPU
(tecnicamente detto p-code [1]) che garantisce sì la portabilità
delle applicazioni realizzate con questo linguaggio, ma al prezzo di una
loro sostanziale esecuzione in modalità interpretata;
-
un ulteriore
aggravio nelle prestazioni causato dall’alta flessibilità del linguaggio
(reflection, introspection e caricamento ed aggiornamento dinamico delle
classi) e dalla sua predilezione nei confronti degli oggetti non riusabili,
cosa che porta ad un alto numero di allocazioni di memoria, per di più
tutte eseguite sullo stack;
-
l’enormità
di API, interfacce e protocolli da apprendere: infatti, l’approccio multipiattaforma
di Java ha obbligato Sun a realizzare un vero e proprio “sistema operativo
virtuale” in grado di isolare completamente le applicazioni dal bisogno
di colloquiare in prima persona con il sistema operativo sottostante, e
nel caso delle applicazioni stand-alone – le quali necessitano di un’interfaccia
grafica evoluta e della possibilità di gestire dati audio/video
- la mole delle librerie da studiare può, senza tema di smentita,
dirsi scoraggiante;
-
il tempo
necessario perché Sun riuscisse a rendere stabili le suddette API:
e chi ne ha risentito maggiormente sono state proprio le API delegate alla
gestione dell’interfaccia grafica e dei dati multimediali, fulcro degli
applicativi stand-alone, e che, dopo un traviato percorso durato non meno
di quattro anni (e ricco di vicoli ciechi ed errori di progettazione) solo
negli ultimi 5-6 mesi, prima con il JDK 1.2.2 ed ora con la versione 1.3,
hanno raggiunto una buona solidità ed efficienza;
-
l’elevata
richiesta di memoria degli ambienti di esecuzione dei programmi in Java,
vale a dire le Java Virtual Machine, immediatamente comprensibile alla
luce dei punti precedenti.
Quello
che cercheremo di capire in questo articolo è se la situazione attuale
costringa ancora il linguaggio Java a proporsi solamente come soluzione
Web-based – nello scenario da me già descritto in [2] - o se sia
invece realistico, ad un anno e mezzo di distanza, un suo utilizzo in tutte
le casistiche di sviluppo e particolarmente in quelle, sino ad oggi considerate
assolutamente ostiche al linguaggio di Sun, legate all’implementazione
di software a carattere gestionale.
La scelta iniziale
Le
idee e le riflessioni contenute in questo articolo si basano su un’esperienza
reale, ancora in corso ed estremamente positiva: vale a dire la realizzazione
di un applicativo stand-alone di tipo gestionale interamente in Java. Si
tratta di una sfida che oggi si può dire vinta, ma che, nelle sue
fasi iniziali, veniva considerata pura follia. Ed è proprio per
spiegare le ragioni di questa sfida, per dimostrarne la sensatezza, e per
convincere i lettori di MokaByte che ora i tempi sono maturi per realizzare
applicativi stand-alone in Java, che non mi limiterò ad elencare
tutte le scelte fatte nel corso della realizzazione del programma, ma cercherò
di spiegare come e perché si arrivò a quelle scelte.
La
storia di questo applicativo - il cui nome è Irmgard - inizia 9-10
mesi orsono, tra la fine di Agosto e l’inizio di Settembre 1999, quando
si presentò a me ed ai miei collaboratori la possibilità
di acquisire una commessa per la realizzazione di un software per la gestione
di ditte di autotrasporti nazionali ed esteri.
I
punti caratterizzanti di questo software avrebbero dovuto essere:
-
Solidità
e sicurezza;
-
potenza
e facilità d’uso;
-
una gestione
a 360 gradi del workflow aziendale, dalla gestione dei documenti fiscali
e dalla schedulazione ed ottimizzazione dei viaggi e degli itinerari dei
mezzi di trasporto sino ad una completa e puntuale analisi dei costi, oltre
a quelle attività collaterali di magazzino in conto deposito frequentemente
effettuate dai trasportatori;
-
possibilità
di integrazione e di interscambio di dati in tempo reale con applicativi
di contabilità commerciale ed industriale;
-
capacità
di comunicazione con applicativi di produttività personale (videoscrittura,
tabelloni elettronici) per la realizzazione di circolari e rapporti analitici;
-
disponibilità
al pubblico, in tempo reale su Internet, delle informazioni di tracking
sullo stato di consegna della merce.
Immediatamente
cominciai a chiedermi se fosse possibile realizzare un progetto così
ambizioso - una prima stima mi portò a prevedere un impegno di tre
anni/uomo - in Java e, soprattutto, se fosse la scelta migliore per noi
e per il cliente.
L’utilizzo
cui sino a quel momento avevamo destinato il linguaggio Java era legato
al Web ed alla realizzazione di servizi su Internet; quanto il know-how
da noi posseduto in quel settore si sarebbe rivelato utile durante la realizzazione
di un applicativo stand-alone ? Perché non continuare a seguire
le nostre usuali metodologie di lavoro, utilizzando per quell’applicativo
i tool di sviluppo comunemente ritenuti più consoni e performanti,
quali Visual Studio e Delphi ?
Inoltre
la portabilità di tale linguaggio– che sarebbe stato il motivo principale
di una sua eventuale scelta per quel progetto – era poco più di
un pio desiderio, in quanto non esisteva un ambiente Java di buon livello
per quella che era l’unica valida alternativa a Windows - e che ora lo
è ancora di più - vale a dire il Linux: in sostanza avremmo
dovuto combattere con tutti i problemi del linguaggio di Sun e rinunciare
alle comodità di Windows per ottenere un programma che di fatto
avrebbe comunque potuto funzionare solamente sotto Windows.
Eppure,
dopo diversi e sofferti giorni di riflessione mi resi conto che, se anche
guardando alla situazione del momento non c’era un solo valido motivo per
abbandonare strumenti e modalità di lavoro noti e consolidati ed
allontanarsi dal mondo Windows, lo scenario mutava radicalmente se lo si
osservava di lì a sei mesi, vale a dire quando avremmo cominciato
a rilasciare le prime beta.
Infatti,
i punti di forza della soluzione Java permanevano, mentre i dubbi ed i
problemi sembravano perdere forza:
-
Ritenni
sufficientemente probabile che la questione delle performance problematiche
di Java nell’utilizzo lato client, legate all’inefficienza ed alla pesantezza
delle API Swing, sarebbero state risolte o dall’allora nascente tecnologia
Hot Spot [3] o semplicemente dalla legge di Moore [4]: vale a dire, la
CPU e la memoria richieste da Java, che allora sembravano spropositate,
sarebbero state considerate accettabili entro sei mesi;
-
IBM stava
entrando con forza nei mercati Linux e Java, cosa che mi faceva ben sperare
per la disponibilità di un JDK degno di questo nome anche sotto
Linux;
-
voci di
corridoio riportavano di progetti da parte di Borland/Inprise, che aveva
collaborato con Sun alla realizzazione del JDK 1.2 (ad esempio nella realizzazione
del protocollo JavaBean), volti al porting del suo ambiente di sviluppo
JBuilder sotto Solaris e Linux: questo ci avrebbe permesso eventualmente
di spostare, o quanto meno di procedere in parallelo, allo sviluppo di
Irmgard anche in quest’ultima piattaforma, conditio sine qua non – a mio
avviso - per garantire un prodotto di qualità sotto tale sistema
operativo.
In
ragione di queste considerazioni, e dell’estremo interesse con cui tutto
il mio team guardava al linguaggio Java – apprezzandone l’eleganza e la
flessibilità, ma soprattutto il design pulito e moderno di gran
parte del suo framework – decisi, tra i dubbi e gli scetticismi di molti
miei colleghi, di imbarcarmi in quest’avventura.
Ci
fu chiaro, fin dall’inizio, che la scelta fatta limitava molto i nostri
margini di errore: non solo avremmo dovuto indovinare la scelta dei tool
e delle metodologie da usare per lo sviluppo, ma – per compensare i limiti
di performance del linguaggio di Sun – avremmo dovuto partire da una fase
di modellazione particolarmente curata, che si sarebbe dovuta tradurre
in un codice ben ottimizzato e di alta qualità, ed era già
preventivabile il bisogno di ricorrere, in alcune situazioni limite, a
qualche escamotage: insomma, una sorta di “ritorno all’antica” nello stile
di programmazione, molto lontano dalla liberalità e dall’utilizzo
a volte sproporzionato delle risorse di sistema che è patrimonio
comune della programmazione in Windows.
Metodologie e
tool di design
Se
l’approccio da seguire nello sviluppo del programma non ha comportato grossi
dubbi – abbiamo infatti seguito il nostro usuale approccio iterativo basato
sul linguaggio UML [5], approccio descritto e raccomandato proprio dai
suoi autori – leggermente più complessa si è rivelata la
scelta del tool di modellazione da utilizzare.
Trovandoci
a lavorare con Java ci sembrò naturale propendere per uno strumento
realizzato proprio in tale linguaggio, e cominciammo quindi a vagliare
ciò che il mercato poteva offrirci, tanto più che, trattandosi
proprio di applicazioni in Java, studiarne il funzionamento anche solo
dall’esterno ci avrebbe potuto fornire degli indizi sui problemi, di interfaccia
e di performance, che di lì a breve ci saremmo sicuramente trovati
a vivere in prima persona.
Purtroppo
nessuno dei tool che avemmo l’occasione di testare ci convinse pienamente:
alcuni erano semplicemente incompleti, altri non si dimostravano sufficientemente
solidi. In particolare, ciò che ci colpì fu vedere come i
tool più solidi fossero legati non solo alle API AWT (cosa che ci
aspettavamo, considerando la situazione estremamente fluida in cui lo Swing
si trovava in quel momento) ma anche ad una specifica JVM. In particolare,
la JVM raccomandata da questi tool - e spesso inclusa direttamente all’interno
della loro distribuzione - era quella di Microsoft.
I
tentativi di utilizzarli con altre Java Virtual Machine, come quella Sun,
si rivelarono infruttuosi: sia la velocità che la stabilità
dei programmi degradava notevolmente, e ad ogni cambio di JVM si manifestavano
nuovi bug nell’interfaccia, che arrivavano fino al punto di rendere l’intera
applicazione inutilizzabile.
D’altro
canto i tool realizzati in Swing erano notevolmente più lenti, e
questa lentezza diveniva addirittura patologica nelle operazioni più
pesanti per l’interfaccia grafica, quali lo scroll o il redraw delle finestre.
Come se ciò non bastasse questi stessi tool mostravano dei preoccupanti
bug nel disegno dell’interfaccia (menu che rimanevano aperti, sezioni di
finestre non tracciate correttamente), bug che sembravano essere comuni
alle diverse applicazioni, segno questo che il problema si trovava ad un
livello superiore, probabilmente nello stesso Swing.
In
sostanza i tool Swing ci sembrarono deludenti, per quell’impressione di
“pesantezza” e di “sofferenza” che a più riprese ci comunicavano:
utilizzandoli avevamo veramente l’impressione di torturare i nostri computer.
Ci piacque però il design delle interfacce: esse si mostravano funzionali
e pulite, così lontane dal widget bloating tipico del mondo Windows.
“Con un po’ più di velocità e qualche bug in meno – ci dicemmo
– questi programmi sarebbero sensazionali”.
Tirando
le somme, decidemmo di continuare ad utilizzare il nostro tool di modellazione
UML consueto, Rational Rose [6], ma di dare di tanto in tanto un’occhiata
a quello che sembrava essere un prodotto promettente, e per di più
open source: Argo UML [7].
Ambiente di sviluppo:
strumenti e parco macchine
Era
chiaro a tutti che un tassello fondamentale nel nostro progetto era la
scelta degli ambienti di sviluppo, e immediata fu la scelta di puntare
sul JDK 1.2 (pomposamente definito da Sun “Java 2”) optando quindi per
una scelta Pure Java al 100%: infatti uno dei nostri obiettivi era sin
dall’inizio quello di realizzare un’applicazione portabile, in grado di
garantire un corretto funzionamento e prestazioni elevate su di una pluralità
di piattaforme, e specificamente sotto Linux, non appena si fosse resa
disponibile un’implementazione di qualità del JDK per il sistema
operativo di Linus Torvalds..
Tuttavia
anche se oggi tale scelta appare ovvia, la situazione si presentava - tra
Settembre ed Ottobre dell’anno scorso - radicalmente diversa.
Le
problematiche performance di Java e la constatazione del fatto che, nonostante
le sue velleità multipiattaforma, il suo utilizzo lato client era
limitato al mondo Windows – sia per l’orientamento che il mercato ancora
aveva in quel momento, sia perché il Linux non era sufficientemente
maturo come soluzione client, tanto più in ragione dell’assenza
di una valida implementazione del linguaggio di Sun per tale piattaforma
– avevano causato una dicotomia di fatto nel mondo Java.
Da
un lato si stagliavano, con Sun, Borland/Inprise ed IBM, gli assertori
del Pure Java, ovvero di soluzioni realizzate con le sole API ufficiali
di tale linguaggio, e – perlomeno nelle intenzioni – portabili verso una
pluralità di piattaforme.
Dall’altro
lato, raccolto intorno a Microsoft, si trovava un discreto numero di ambienti
di sviluppo che coniugavano il linguaggio Java con le API Windows, e spesso
con una compilazione diretta delle applicazioni in file .exe, con evidenti
benefici in termini di facilità di deployment e di performance.
Forse qualcuno ancora ricorda lo slogan di Microsoft secondo cui Java veniva
considerato, alla stessa stregua del C++, solamente come un altro linguaggio
per la realizzazione di applicativi Windows. La stessa Microsoft aveva
agio nel difendere tale posizione paragonando le buone prestazioni del
suo ambiente di sviluppo proprietario in Java, basato sull’abbandono dello
Swing e di parte delle JFC in favore di una diretta coesione con le API
Windows, con tutti i problemi di performance e stabilità che affliggevano
il mercato delle Pure Java IDE.
Compiuta
quindi questa scelta di campo, che per nostra fortuna si è poi rivelata
corretta - tutti gli ambienti di sviluppo della seconda schiera, molti
dei quali erano dei veri e propri “nomi eccellenti”, oggi non esistono
più o sono relegati ai margini del mercato, così come sono
scomparse molte delle ditte che li producevano - bisognava però
orientarsi nel mercato delle soluzioni Pure Java.
Anche
qui, semplificando, si presentavano al nostro team due possibilità:
utilizzare ambienti di sviluppo nativi in Windows, o puntare fin dall’inizio
su IDE realizzate esse stesse interamente in Java. Di questo secondo gruppo
valutammo Java Studio di Sun, prodotto in seguito lasciato morire, e NetBeans
- successivamente acquisito da Sun proprio a rimpiazzo di Java Studio e
ridenominato Forte For Java Community Edition [8], reso open-source [9]
dalla stessa Sun all’inizio di Giugno - trovandoli entrambi assolutamente
inutilizzabili: se alla lentezza ed ai bug delle applicazioni in Java si
aggiungevano anche la lentezza ed i bug degli ambienti di sviluppo realizzati
tale linguaggio, i problemi di performance e solidità sembravano
addirittura elevarsi al quadrato, rendendo lo sviluppo un’esperienza a
dir poco frustrante.
Questo
costituiva per noi un grave problema: perché si potesse avverare
il nostro progetto di sviluppo parallelo sotto più piattaforme era
evidente che la possibilità di disporre di un ambiente di lavoro
unico avrebbe facilitato enormemente le cose dal punto di vista pratico,
permettendoci di concentrarci su di un unico prodotto, imparando a conoscerne
al meglio pregi e difetti, ed eventualmente dandoci la possibilità
– nelle tanto paventate “situazioni limite” - di sfruttarne il framework
proprietario per risolvere i più gravi problemi di performance e
di implementazione che prevedevamo si sarebbero presentati.
Tuttavia
l’incapacità delle IDE in Java di proporsi come soluzioni efficaci
al nostro problema ci spinse, per il momento, ad accantonare l’idea dello
sviluppo in parallelo, e ad orientarci verso IDE Pure Java specificamente
realizzate in Windows. Le tre IDE che valutammo più approfonditamente
furono Visual Age for Java di IBM, Visual Café di Symantec, e JBuilder
di Borland/Inprise.
Il
primo si dimostrò essere un prodotto solido, e molto adatto allo
sviluppo collaborativo: dovemmo però scartarlo non tanto per la
sua metafora di programmazione visuale, molto potente ma secondo noi eccessivamente
prolissa, quanto per la mancanza di supporto da parte di IBM al JDK 1.2,
la piattaforma Java che noi avevamo identificato come strategica. Visual
Age era infatti legato al JDK 1.1.8, ed IBM non sembrava intenzionata ad
effettuarne un upgrade (per la cronaca, IBM ha sostanzialmente “saltato”
il JDK 1.2 passando direttamente dalla versione 1.1.8 a quella 1.3, che
– è notizia di pochi giorni fa - ha deciso di implementare in prima
persona su diverse piattaforme, tra cui Linux e Windows, oltre a tutti
i suoi ambienti “storici” quali AIX, AS/400 ed OS/390).
Per
quanto riguarda Visual Café di Symantec, era un prodotto che avevo
già avuto modo di utilizzare in prima persona nella realizzazione
di un’applicazione AWT ai tempi della prima release del Java Media Framework
[10]. Lo trovammo ricco di bug e molto scomodo, in virtù della sua
interfaccia basata su un eccessivo numero di finestre indipendenti, che
finivano con il sovrapporsi e nascondersi l’un l’altra; inoltre ci sembrava
pendere pericolosamente verso il mondo Windows, per via del supporto per
la compilazione nativa e per la presenza di alcuni componenti, in un formato
tra l’altro alternativo a quello JavaBean, esplicitamente congegnati per
funzionare solamente con il sistema operativo di Bill Gates. Aggiungerò
infine che la stessa Symantec non era molta chiara nei suoi progetti di
sviluppo futuro di Visual Café, e sembrava propendere verso soluzioni
proprietarie ai problemi di Java, tanto da includere nel suo prodotto un
supporto tardivo ed incompleto per il JDK 1.2 e per le API Swing.
Di
JBuilder, prodotto di Borland/Inprise, avevamo avuto un’esperienza della
primissima ora, con la versione 1.0 di tale IDE. Essa era di una fragilità
e di una lentezza inverosimili – non degne nemmeno di una beta - tanto
da convincerci ad abbandonarla completamente, e ad ignorare la versione
2.0. Ragion per cui, quando ci trovammo dinanzi la versione 3.0 di JBuilder,
la approcciammo con molto scetticismo.
Dovemmo
invece constatare che molte cose erano cambiate:
-
JBuilder
aveva acquisito stabilità: era possibile – su macchine con potenza
e memoria adeguate - utilizzarlo a lungo e senza riscontrare problemi;
-
le performance
dell’ambiente di lavoro erano visibilmente aumentate, per quanto JBuilder
restasse sempre un po’ più lento delle altre IDE Windows, essendo
realizzato parte in Java e parte in codice nativo Windows (ed alcune piccole
differenze nell’interfaccia grafica, curiosamente, rendevano possibile
riconoscere ad occhio le diverse sezioni). D’altronde questo era per noi
un aspetto fortemente positivo: Borland/Inprise si trovava infatti ad avere
una buona IDE in grado di migrare, senza sforzi sovrumani, su altre piattaforme
quando ce ne fosse stata la possibilità tecnica, situazione che
si combinava perfettamente con l’idea di un ambiente di sviluppo unico
per noi ancora valida in proiezione futura;
-
più
di tutti i suoi concorrenti, JBuilder sembrava essere scritto nel rispetto
degli standard Java: non solo esso supportava pienamente il JDK 1.2 e le
JFC, al cui sviluppo Borland/Inprise aveva collaborato assieme a Sun, ma
la stessa Borland/Inprise aveva apertamente abbandonato il suo precedente
framework proprietario in Java (JBCL) – che manteneva unicamente per motivi
di compatibilità all’indietro - indirizzando tutti i suoi sforzi
nella realizzazione della sola IDE sul mercato il cui supporto alla programmazione
visuale supportasse pienamente e nel modo più corretto lo Swing
(forse i lettori si ricorderanno come, in quei tempi, il supporto Swing
venisse “appiccicato” nelle varie IDE sopra a quello per l’AWT causando
tutt’una serie di problemi, ad esempio nella gestione dei Pane);
-
come già
detto, voci di corridoio parlavano di sforzi in atto all’interno di Borland/Inprise
per il porting di JBuilder sotto Linux, cosa che lo rendeva ancora più
appetibile ai nostri occhi;
-
la soluzione
JBuilder non si limitava allo sviluppo di applicazioni stand-alone, ma
comprendeva un supporto completo dei protocolli standard utilizzati nella
programmazione multi-tier distribuita ed Internet-based, come CORBA e servlet,
vale a dire proprio l’utilizzo che noi avevamo fino a quel momento fatto
di Java, e che rimaneva per noi assolutamente strategico;
-
infine,
come d’altronde già nelle precedenti versioni, JBuilder si segnalava
per un’interfaccia ben progettata e funzionale, basata su un numero limitato
di finestre organizzate in pannelli affiancati, che permetteva di seguire
con naturalezza e facilità più progetti contemporaneamente.
Alla
luce di queste considerazioni scegliemmo la versione 3.0 di JBuilder come
piattaforma di sviluppo per Irmgard, sviluppo che sarebbe stato portato
avanti su macchine NT.
Siccome
almeno per il momento non potevamo fare a meno di lavorare su macchine
Windows, decidemmo di usare anche per questo progetto Visual Source Safe
di Microsoft come source code control system, riservandoci di passare a
CVS [11], sotto Unix/Linux, in una fase successiva.
A
livello di curiosità, dirò come fu per noi una piacevole
sorpresa constatare che, al contrario di Delphi, JBuilder era in grado
di “sentire” le modifiche apportate ai file sorgenti dall’esterno, e di
bloccare le modifiche ad un file attraverso l’editor non appena ne veniva
impostata la proprietà read-only, permettendoci così di utilizzare
Source Safe – che opera proprio in questo modo - nella maniera più
semplice possibile, e senza bisogno di alcun plug-in.
Consci
dei requisiti richiesti da JBuilder, per lo sviluppo ci orientammo su delle
macchine Pentium a 300-350 MHz, con 256 MB di RAM, dischi EIDE e Windows
NT Workstation 4 SP3. Con una tale quantità di RAM JBuilder diventava
sufficientemente veloce e molto affidabile: al contrario di quanto accadeva
con la versione 1.0, nessuno di noi ha mai perso una sola riga di codice
per un suo crash. La scelta di NT poi, per quanto sicuramente penalizzante
in termini di prestazioni, ci garantiva una ancora maggiore solidità.
Come
repository del programma utilizzammo il nostro server di supporto, una
macchina con delle caratteristiche simili a quelle sopra elencate, con
architettura SCSI e Windows NT Server 4 SP3 installato.
La gestione dei
dati
Assieme
alla versione 1.1 delle API JFC/Swing, uno dei punti qualificanti nella
nostra scelta del JDK 1.2 era costituito dalla versione 2 del framework
JDBC [12], framework di cui possedevamo già una ampia esperienza.
Dunque, nella scelta del database da utilizzare con Irmgard il supporto
delle API JDBC sarebbe stato un fattore importante, secondo solo a solidità
, performance e portabilità.
Era
per noi evidente che, come Irmgard avrebbe dovuto essere in grado di operare
in reti con architetture diverse, basate sia su Windows che su Unix, così
avrebbe dovuto essere il suo database server: un server multipiattaforma
in grado di seguire i clienti nei loro percorsi di migrazione senza costringerli
a scomodi, e sempre pericolosi, cambi di prodotto.
Come
prima cosa, dunque, sondammo il mercato alla ricerca di soluzioni object-oriented:
realizzando infatti il programma in Java, sarebbe stato necessario implementare
uno strato di conversione tra gli oggetti in archivio e la loro rappresentazione
in memoria, e sarebbe stato per noi un risparmio di tempo notevole trovarci
con questa conversione già pronta, o perlomeno avviata.
Tuttavia
emerse immediatamente un problema, e cioè che, anche se era possibile
rintracciare dei database ad oggetti con le caratteristiche da noi richieste,
non esistevano implementazioni JDBC in grado di supportare in maniera soddisfacente
le metafore ad oggetti, e tanto meno il linguaggio OQL [13]. Difatti, sia
nel parco dei database pure-object, sia in quelli ibridi object-relational,
la maturazione cui questi prodotti erano arrivati nell'ultimo anno era
completamente mascherata proprio dall’indisponibilità di validi
driver JDBC, cosa che ci costrinse ad optare per una soluzione SQL.
Prima
di optare per una classica soluzione commerciale cogliemmo l’occasione
per sperimentare alcuni database SQL open-source, dovendo però constatare
la loro incapacità di supportare basi di dati specificatamente gestionali.
Laddove essi non mancassero addirittura di alcuni tipi di dati per noi
fondamentali - come le colonne DECIMAL di ampie dimensioni richieste per
la memorizzazione di valori valutari internazionali ed in Euro ma non presenti
in PostgreSQL [14] - erano proprio performance e stabilità a lasciarci
perplessi: trovandosi a gestire grandi moli di dati, non basta che un database
SQL funzioni; occorre anche che funzioni bene, vale a dire che si basi
su uno schema di memorizzazione evoluto, in grado di assicurare affidabilità
in caso di crash e velocità nel reperimento e nell’archiviazione
delle informazioni, oltre ad un supporto completo del linguaggio SQL, aspetti
in cui tutti i database open-source testati mostravano la corda.
Da
questo punto di vista una grande delusione fu per noi il database MySQL
[15]: esso infatti, oltre a non essere realmente open-source, è
completamente privo di qualsiasi forma di supporto transazionale. I suoi
autori hanno optato, piuttosto, per un’architettura basata sul concetto
di operazioni atomiche [16], scelta che garantisce una semplicità
ed una velocità notevoli, ed è senz’altro adatta ad un ampio
ventaglio di situazioni – prime tra tutte le basi dati Internet-based in
cui, e non è un caso, MySQL si sta rapidamente affermando - ma non
offre quei requisiti di solidità ed affidabilità fondamentali
nel deployment di sistemi informativi gestionali e finanziari.
Aggiungerò
poi come anche nelle implementazioni open-source di miglior livello il
collo di bottiglia fosse rappresentato dai driver JDBC, di qualità
– senza voler esagerare – poco più che hobbystica ed assolutamente
inadatti alla memorizzazione delle informazioni vitali di un’azienda.
Alla
luce dell’insufficienza delle proposte open-source la nostra attenzione
si rivolse dunque ai database SQL commerciali, in particolare a DB2 di
IBM e a Dynamic Workgroup Server di Informix, entrambi disponibili per
un vasto parco di piattaforme (al tempo Informix non aveva ancora rilasciato
Cloudscape [17], la sua soluzione integralmente basata su Java): la scelta
di un database commerciale, inoltre, avrebbe rappresentato un’importante
sorta di “compensazione” – se non altro psicologica – al rischio assunto
scegliendo Java come linguaggio di sviluppo, e si sarebbe rivelata in seguito,
nei momenti più difficili di questo progetto, una certezza molto
importante per tutto il team di progettazione.
Sia
DB2 che Dynamic Workgroup Server rappresentavano delle scelte valide: il
primo era, ed è, molto noto per le sue performance e si segnalava
per l’approccio Java-based della sua console di amministrazione. Il secondo
al contrario era un prodotto più classico, il cui supporto Java
era limitato ai driver JDBC, mentre il resto del database, console di amministrazione
inclusa, era realizzato interamente in codice nativo.
Controintuitivamente
però i driver JDBC realizzati da Informix si rivelarono nei nostri
test superiori a quelli di DB2:
-
I driver
Informix supportavano il JDK 1.2 ed il JDBC 2, mentre quelli DB2 erano
– come tutta IBM, d’altronde – ancora fossilizzati nel supporto del JDK
1.1.8 e del JDBC 1.1, ed i driver sperimentali per il supporto del JDBC
2 presentavano seri problemi di funzionamento;
-
il supporto
di DB2 all’ormai obsoleto JDBC 1.1 causava una serie di problemi nell’accesso
ad alcuni tipi di colonne, ed in particolare a quelle BigDecimal, fondamentali
nelle applicazioni gestionali;
-
i driver
Informix erano caratterizzati da un’installazione “leggera”: infatti, per
abilitare i client all’accesso al database era sufficiente inserire nel
CLASSPATH il solo file .jar del driver - che poteva anche trovarsi in un
server di rete - mentre nel caso di DB2 occorreva installare l’intera suite
DB2 client in ogni pc destinato a connettersi al database. L’alternativa
consistente nel configurare il prodotto di IBM sui client in maniera da
utilizzare in modalità proxy i driver installati nel server, ottenendo
quindi un’installazione “leggera”, comportava un aumento inaccettabile
dei tempi di accesso, i quali arrivavano sino al punto di triplicarsi o
quadruplicarsi;
-
i driver
JDBC di DB2 avevano dei problemi di configurazione a livello di JBuilder,
cosa che ci obbligava ad utilizzarli in modalità proxy, subendo
quindi tutte le inefficienze sopra descritte.
Aggiungendo
a tutto questo la mancanza, nell’SQL di DB2, di alcuni comandi di gestione
delle tabelle (RENAME TABLE e DROP COLUMN) non facenti parte dello standard
ANSI-SQL 92 [18], ma estremamente utili nella fase di design di una base
di dati, e la considerazione di come tutto il team di sviluppo già
conoscesse ed apprezzasse i prodotti Informix, su cui avevamo basato molti
dei nostri progetti precedenti, e a cui tutti riconoscevamo una solidità
ed una stabilità eccezionali, la scelta del Dynamic Workgroup Server
appariva quasi dovuta. Nei primi mesi di sviluppo la piattaforma usata
per il database fu un server NT, da cui si migrò su di una macchina
Linux dopo un paio di mesi (tra Novembre e Dicembre) non appena i nostri
test interni mostrarono la stabilità della versione del server Informix
su tale piattaforma.
La
scelta di un database relazionale SQL (per cui esistevano anche delle estensioni
ad oggetti, vale a dire i moduli Informix DataBlade [19], tuttavia – ancora
una volta - non accessibili tramite JDBC) ci costrinse ad implementare
in prima persona lo strato di traduzione object-relational all’interno
di Irmgard: si trattò di un lavoro molto impegnativo, sia in fase
di design che in fase di codifica, ma che – con il senno di poi – si è
rivelato sicuramente proficuo, in quanto è stato proprio a questo
livello che si è potuto intervenire con importanti ottimizzazioni
del codice.
Ad
ogni modo prima di risolverci a realizzare questa parte del framework,
sostanzialmente analoga a quanto fatto oggi da Castor [20], valutammo anche
altre ricoperture del JDBC che offrivano un accesso ai dati di natura più
object-oriented, come Village [21] e Town [22]: tuttavia le API da esse
fornite, per quanto eleganti, si rivelarono alla prova dei fatti incomplete
e caratterizzate da un’inefficienza per noi non tollerabile.
Come
curiosità citerò un problema che si presentò nell’utilizzo
dei driver JDBC Informix: essi infatti, per evitare possibili malfunzionamenti,
controllavano che la versione del JDK al cui interno venivano eseguiti
fosse almeno la 1.2, rifiutandosi di funzionare se così non era.
Purtroppo
se al JDK 1.2 veniva aggiunto Hot Spot 1.01, questo riconoscimento di versione
falliva, impedendo effettivamente l’avvio del programma. La soluzione,
consigliata negli stessi newsgroup Informix, fu quella di forzare il valore
dell’impostazione java.vm.version controllata da tali driver aggiungendo
l'opzione –Djava.vm.version=1.2 (o –Djava.vm.version=1.2.2 per il JDK 1.2.2)
nell’invocazione della JVM di Irmgard. Questa leggera incompatibilità
non si manifestava invece eseguendo Irmgard dall’interno di JBuilder 3.0,
il quale lavorava senza Hot Spot.
Il punto della
situazione
Nella
prima parte di questo articolo, appena conclusa, abbiamo esaurito l’argomento
delle scelte fondamentali su cui è basato il progetto Irmgard. Nel
prossimo mese esamineremo in dettaglio l’architettura della nostra applicazione,
con particolare riguardo al suo framework
Bibliografia
[1]
– P-code e UCSD p-system: http://www.ics.uci.edu/~archive/documentation/p-system/p-system.html
[2]
- Lavinio Cerquetti, “Java Servlet all’opera”, Computer Programming No.77,
Febbraio 1999 e MokaByte no.29, Aprile 1999: http://www.mokabyte.it/0499/servlet.htm
[3]
- Hot Spot: http://java.sun.com/products/hotspot, http://developer.java.sun.com/developer/technicalArticles/Networking/HotSpot
[4]
- La legge di Moore: http://www.webopedia.com/TERM/M/Moores_Law.html
[5]
- UML: http://www.rational.com/uml, http://www.uml-zone.com
[6]
- Rational Rose: http://www.rational.com/products/rose
[7]
- ArgoUML: http://argouml.tigris.org
[8]
- Forte For Java, Community Edition: http://www.sun.com/forte/ffj/ce
[9]
- NetBeans Open-Source: http://www.netbeans.org
[10]
- Java Media Framework: http://java.sun.com/products/java-media/jmf
[11]
- CVS: http://www.cvshome.org
[12]
- JDBC: http://java.sun.com/products/jdbc
[13]
- OQL: http://www-cse.ucsd.edu/classes/wi00/cse132a/oql.htm
[14]
- PostgreSQL: http://www.postgresql.org
[15]
- MySQL: http://www.mysql.org
[16]
- Le operazioni atomiche in MySQL: http://web.mysql.com/Manual/manual.html#Missing_Transactions
[17]
- Informix Cloudscape: http://www.informix.com/cloudscape
[18]
- ANSI-SQL 92: http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
[19]
- Informix DataBlade: http://www.informix.com/datablades
[20]
- Castor: http://castor.exolab.org
[21]
- Village: http://www.working-dogs.com/village
[22]
- Town: http://www.working-dogs.com/town
Lavinio
Cerquetti si occupa di modellazione e sviluppo del software (prevalentemente
in Java, C/C++ e Delphi) in ambienti Windows e Unix, concentrandosi sulla
programmazione distribuita e di rete. Può essere contattato all’indirizzo
di e-mail lavinio@poboxes.com |