MokaByte 78 - 8bre 2003 
Jakarta Commons
I parte: panoramica
di
Alessandro "Kazuma" Garbagnati
Per evitare di continuare a riscrivere sempre gli stessi moduli, all'interno dei differenti progetti, il gruppo Jakarta dell'"Apache Foundation" ha creato un contenitore dove mantenere i componenti e le librerie di uso comune. In poco tempo è nato un progetto chiamato "Commons".

Introduzione
Lo scrivere software riutilizzabile è uno degli obiettivi primari di tutti i team di programmazione, indipendentemente dalla loro dimensione. Il gruppo Jakarta dell'Apache Foundation è un esempio di come si possano realizzare e portare avanti progetti riutilizzabili, al punto tale che alcuni di questi o hanno contribuito alla definizione di nuovi standard da parte di Sun o sono diventati prodotti e framework largamente diffusi anche all'interno di ambienti di produzione.
Ma il gruppo Jakarta non si è fermato solo qui. Alcuni dei moduli che componevano i differenti progetti hanno attratto l'attenzione della comunità al punto tale da convincere gli architetti del gruppo a staccarli e generalizzarli per trasformarli, a loro volta, in progetti a se stanti. L'esempio più eclatante di questa operazione di decoupling è, senza dubbio, il progetto Jakarta Commons.

 

La struttura
Se si volesse definire con una sola parola Jakarta Commons, si potrebbe semplicemente utilizzare proprio il termine inglese "reusability", ad indicare come, negli obiettivi dei vari creatori del progetto, fosse chiara l'idea di costruire un repository che contenesse librerie e componenti Java, in modo da renderli disponibili e, soprattutto, facilmente gestibili.


Figura 1
- La homepage del progetto Jakarta Commons

Nel pieno rispetto delle regole dell'Open Source, chiunque può partecipare allo sviluppo dei vari componenti che fanno parte di Commons e, allo stesso tempo, è libero di proporne e di inizarne di nuovi, senza alcun problema, rispettando, ovviamente, le regole del progetto. Tutte queste iniziative, però, non entrano immediatamente a far parte delle librerie e dei componenti ufficiali, ma hanno a disposizione un'area, chiamata "The Sandbox", nella quale far nascere e crescere le idee.
Quello che si trova all'interno di quest'area, però, è da considerarsi in fase di test quindi, tendenzialmente non affidabili anche perché non è detto che lo sviluppo continui. Allo stesso tempo l'idea è comunque disponibile, anche perché può suscitare ulteriore interesse e, quindi, coinvolgere altri sviluppatori per portarla avanti e, magari, completarla.
Nell'altra area, quella a cui è stato assegnato il nome "The Commons Proper", è possibile trovare tutti i componenti e le librerie ufficiali che hanno già passato quella fase di test e, quindi, sono stati ritenuti validi per la loro inclusione nell'area, oppure sono nati originariamente come moduli all'interno di altri progetti e sono stati estratti da questi per renderli disponibili sia agli sviluppatori del gruppo che all'intera comunità Java. Tra questi è importante citare il "Logging", il sistema di gestione dei log che è, oramai, diventato lo standard all'interno di tutti i progetti Jakarta, oppure il sistema di validazione "Validator" che è stato preso dall'interno del codice di Struts.
Tutti i componenti ufficiali di Commons, quindi non facenti parte del "Sandbox", non sono raggruppati o indicizzati in alcun modo. Probabilmente questa è stata una scelta che è stata fatta per non dare l'impressione che i vari componenti avessero possibilità di utilizzo più limitate rispetto a quelle pensate in fase di disegno. All'interno di questo articolo abbiamo però pensato che sia più semplice cercare di suddividere i vari componenti in gruppi che tengano conto delle funzionalità primarie, in modo da fornire una prima idea:

1) Base: BeanUtils, CLI, Collections, Lang
2) Avanzate: Daemon, Logging, Pool, Validator
3) Database: DBCP
4) XML: Betwixt, Digester, Jelly, Jexl, JXPath
5) Web/Network: EL, FileUpload, HTTPClient, Lakta, Net
6) Altre: Codec, Discovery, Modeler

E' comunque importante ricordare che questa categorizzazione è puramente arbitraria.


Utilities di base
All'interno di questo gruppo ho voluto inserire quattro librerie a mio parere fondamentali per chi sviluppa software con Java. Si tratta di BeanUtils, CLI, Collections e Lang.

Il componente più rappresentativo che ho inserito in questa categoria è, senza dubbio, Commons Lang (http://jakarta.apache.org/commons/lang.html), che raccoglie una serie di classi eterogenee all'interno di una singola libreria. Così come hanno fatto tutti gli sviluppatori, siano loro singoli o parte di un team, anche il gruppo Jakarta ha voluto raccogliere all'interno di un unico repository, sia tutte quelle funzionalità che erano mancanti all'interno della Standard Edition di Java, sia quelle operazioni che spesso richiedevano la scrittura, ripetuta, delle stesse linee di codice. Lang fornisce esattamente questo, una serie di classi, molte delle quali composte solo da metodi statici, dirette alla manipolazione delle stringhe, dei numeri, che completano e semplificano le operazioni legate alla reflection, alla serializzazione, alla gestione degli array e così via.

Per chi utilizza in modo costante il Collection Framework, che fa parte della Java 2 Standard Edition, il componente Commons Collections (http://jakarta.apache.org/commons/collections.html) è sicuramente uno strumento a cui dedicare un po' di attenzione. Anche in questo caso, così come per Lang, la libreria nasce con lo scopo di coprire una serie di piccole mancanze che caratterizzano proprio il Framework principale. La libreria di Jakarta contiene differenti implementazioni di List e Map, fornendo, quindi, soluzioni talvolta più complete o con maggior potenzialità, talvolta più veloci ed efficaci. In aggiunta bisogna anche notare l'inserimento di due packages, uno dei quali dedicato ai Comparators e l'altro agli Iterators, entrambi contenenti implementazioni di queste due interfacce. A completare il tutto va sottolineata anche la presenza di una serie di classi di utilities specifiche per questo argomento.

Così come abbiamo visto per Collections, anche Commons BeanUtils (http://jakarta.apache.org/commons/beanutils.html) è uno strumento da analizzare con un po' di attenzione, in quanto fornisce alcune interessanti soluzioni per gli sviluppatori che fanno un uso avanzato dei JavaBeans. Questa libreria mette a disposizione degli sviluppatori diversi tipi di classi. Da una parte si trovano quelle atte a semplificare l'accesso alle API di Reflection e di Introspection, il cui uso è, talvolta, piuttosto complesso. Tra le altre vi sono quelle che forniscono un sistema di gestione dinamica dei beans (i DynaBean), il cui utilizzo è uno dei punti di forza di Struts, il framework per web applications del gruppo Jakarta.
L'ultimo componente che ho voluto inserire all'interno di questa categoria è Commons CLI (http://jakarta.apache.org/commons/cli/index.html), che propone una soluzione al problema della gestione degli argomenti che vengono passati ad un programma. Credo che tutti i programmatori, almeno una volta nella loro vita lavorativa, si siano imbattuti in questo problema. Le soluzioni sono sempre molto semplici, ma ogni volta ci si ritrova a dover riscrivere bene o male lo stesso codice. CLI, acronimo di "Command Line Interface", fornisce un sistema semplice e piuttosto standard al problema, occupandosi di tutte quelle che sono le operazioni di base, lasciando allo sviluppatore il solo compito di definire quali opzioni sono ammesse e, ovviamente, le operazioni che ne conseguono.

 

Utilities Avanzate
Anche all'interno di questa categoria si trovano 4 componenti (Daemon, Logging, Pool, Validator) il cui utilizzo è sicuramente più avanzato rispetto alle utilities di base viste in precedenza.
Sebbene non sia ancora stata rilasciata una versione definitiva, il componente Commons Daemon (http://jakarta.apache.org/commons/daemon/) è sicuramente molto interessante. Il progetto cerca di trovare un sistema standard che consenta di notificare alle applicazioni non interattive (normalmente server) che il sistema è in fase di shutdown. Vi sono alcune soluzioni al problema, ma non ne esiste ancora una standard che, magari, sfrutti le potenzialità offerte da tutti i sistemi operativi multiuser, ed è per questo che Common Daemon ha una struttura "anomala", nella quale esiste una parte realizzata in C, che si interfaccia con il sistema operativo sottostante, e l'altra scritta in Java che fornisce le Daemon API.

Con la versione 1.4 del linguaggio, Sun ha voluto inserire all'interno del JDK un sistema di Log. Questo sistema può rivelarsi sufficiente per semplici applicazioni, ma quando è necessaria una gestione più completa (e quindi complessa) dei log, bisogna intervenire scrivendo del codice, oppure utilizzando librerie esterne come Log4J, altro prodotto del gruppo Jakarta. Commons Logging (http://jakarta.apache.org/commons/logging.html) non è, come potrebbe far pensare il nome, un nuovo sistema di logging, bensì una semplice interfaccia che consente la gestione di log indipendentemente dalle API che vengono utilizzate, togliendo allo sviluppatore l'onore di occuparsi delle problematiche specifiche al sistema di log scelto.

Commons Validator (http://jakarta.apache.org/commons/validator/index.html), come già accennato in precedenza, è nato come modulo interno di Jakarta Struts. Il suo successo e, soprattutto, la possibilità di utilizzarlo al di fuori del mondo web, hanno collaborato alla decisione di creare da questo modulo un componente generico, ed inserirlo all'interno del progetto Commons.
Validator fornisce un sistema che verifica l'integrità dei dati provenienti da un utente sia direttamente (all'interno dei classici moduli di interfaccia utente), sia attraverso moduli web provenienti dalla rete. Tramite questo sistema viene semplificato il lavoro dello sviluppatore sia perché utilizza lo stesso sistema di validazione per tutti i dati appartenenti alla stessa tipologia e sia perché il sistema di gestione degli errori si appoggia sul sistema di internazionalizzazione offerto dal linguaggio, semplificando anche la gestione di prodotti multilingue.

Quando si scrivono applicazioni multiutente per evitare di sprecare troppe risorse o anche per ottimizzarne l'uso, si cerca sempre di trovare soluzioni allo scopo di riutilizzarle. Commons Pool (http://jakarta.apache.org/commons/pool/) fornisce un sistema proprio per risolvere questo problema, non solo attraverso un'interfaccia generica, ma anche grazie ad alcune implementazioni comuni e, soprattutto, a strumenti che facilitano la costruzione di altre implementazioni specifiche.

 

Utilities Database
Nonostante sia composta da un solo DBCP, ho voluto differenziare questa categoria dalle altre, proprio in virtù delle caratteristiche del suo componente.

Commons DBCP (http://jakarta.apache.org/commons/dbcp/) è una implementazione di Commons Pool, specifica per la gestione delle connessioni ad un database. DBCP, infatti, è l'acronimo di DataBase Connection Pooling. Totalmente indipendente dal tipo di database che si vuole utilizzare, DBCP consente di inizializzare e gestire un pool di connessioni ad un database, in maniera completamente trasparente e migliorando le prestazioni delle applicazioni.


Figura 2
- La pagina principale del componente DBCP

Questo componente è nato nonostante fossero già presenti un alto numero di progetti simili, sia all'interno del gruppo Apache Jakarta, sia esternamente. La ragione di questa iniziativa è, comunque, sempre da collegare alla volontà del gruppo di trovare una soluzione valida, unica, che possa sia essere utilizzata all'interno degli altri progetti (Jakarta Tomcat già lo utilizza), sia dal resto della comunità di sviluppatori Java.

 

Utilities XML
Questa categoria comprende 5 componenti (Betwixt, Digester, Jelly, Jexl, JXPath) legati fra loro dalla loro iterazione con l'eXtended Markup Language.

Sempre più frequentemente l'XML viene utilizzato come file di configurazione. Diventa quindi sempre più importante trovare un sistema che consenta di trasferire le informazioni inserite all'interno del file verso Java. Commons Digester (http://jakarta.apache.org/commons/digester.html) è il componente del progetto che permette di gestire il mapping tra un file in formato XML ed uno o più oggetti Java, attraverso la logica dei "triggers" e delle "regole". Quando, all'interno del nostro documento, il sistema incontra un determinato pattern (ad esempio una singola o combinazione di tag) applica una serie di regole, che altro non sono che azioni eseguite all'interno del codice.
Digester, di base, fornisce un completo set di regole, ma consente allo sviluppatore di aggiungerne di proprie. Lo stesso vale per il sistema di riconoscimento dei pattern, che può essere esteso.
Sebbene non troppo pubblicizzato, Commons Digester contiene anche un package che permette la "digestione" di documenti in formato RSS (Rich Site Summary), oramai diventato quasi uno standard per la diffusione di news all'interno della rete.

Se con Digester si poteva trasformare un documento XML in uno o più beans, con Commons Betwixt (http://jakarta.apache.org/commons/betwixt/index.html) si ottiene il risultato opposto, ossia quello di trasformare uno o più beans in un documento XML. Il sistema che viene utilizzato per realizzare questa operazione si basa sulla stessa logica utilizzata dalle classi di introspezione e dalle specifiche di Sun relative ai BeanInfo dei JavaBeans. Il componente, comunque, è disponibile solo in versione alpha.

Commons JXPath (http://jakarta.apache.org/commons/jxpath/index.html) è il tentativo di utilizzare la sintassi di Xpath all'interno di oggetti Java, come beans, collezioni, array e mappe. Xpath è uno standard del W3Consortium e permette di navigare all'interno di un documento XML attraverso una struttura simile a quella di una directory, fornendo, allo stesso tempo, alcune funzionalità tra cui le iterazioni e le condizioni. Questo componente cerca di applicare la stessa logica agli oggetti Java, consentendone la navigazione attraverso la stessa sintassi e le stesse funzioni.
Commons Jelly (http://jakarta.apache.org/commons/jelly/index.html) è un motore di scripting in XML. L'idea è quella di creare un sistema univoco, potente e soprattutto estensibile, attraverso l'uso di azioni, simili ai task di Ant e di tags, la cui struttura, anche a livello di progettazione, ricorda molto da vicino quella delle custom tags JSP. Il componente è stato sviluppato per essere utilizzato sia dalla linea di comando, sia all'interno di applicazioni.
L'ultimo componente, Commons Jexl (http://jakarta.apache.org/commons/jexl.html) fornisce il motore di un "expression language" che può essere utilizzato all'interno di applicazioni e di framework e che ricorda il linguaggio presente all'interno di JSTL. Quello che rende Jexl molto interessante è che può in alcuni casi essere utilizzato per eseguire codice in runtime, un po' come l'eval del perl o del javascript.

 

Utilities Web
All'interno di questa categoria ho voluto includere sia i componenti strettamente legati al Web, sia quelli che sono più legati al networking generico. I 5 componenti contenuti all'interno di questa categoria sono EL, FileUpload, HttpClient, Lakta e Net.

Commons Net (http://jakarta.apache.org/commons/net/index.html) è un componente il cui sviluppo è stato iniziato da una società americana (ORO, Inc.) come prodotto commerciale che, alla chiusura della società, è stato preso in mano dal gruppo Jakarta. L'idea all'origine del progetto consisteva nel creare una serie completa di librerie di networking che comprendesse la maggior parte dei protocolli di accesso di rete, sia quelli più famosi, come POP3, FTP, SMTP, NNTP, Telnet e Finger, sia alcuni tra quelli meno diffusi, come Whois, TFTP, Time ed Echo.

Sebbene sia possibile utilizzare le classi di base offerte dalla Java 2 Standard Edition sfruttando il protocollo HTTP per poter accedere a risorse esterne attraverso la rete, il gruppo Jakarta ha voluto semplificare questi accessi, inserendo, all'interno del proprio progetto, Commons HttpClient (http://jakarta.apache.org/commons/httpclient/index.html). Questo componente consente di utilizzare appieno le potenzialità del protocollo, compreso sia il supporto per SSL (HHTPS), che le connessioni attraverso l'uso di proxy. HttpClient è stato studiato per facilitare la costruzione di applicazioni che possano usufruire totalmente di questo protocollo permettendo, ad esempio, l'accesso a siti web dall'interno dell'applicazione stessa.

Commons FileUpload (http://jakarta.apache.org/commons/fileupload/index.html), come è facilmente intuibile dal nome, è il componente che è stato ideato e sviluppato per permettere agli sviluppatori Java di aggiungere in modo semplice e veloce capacità di file uploading alle applicazioni web.

Commons Lakta (http://jakarta.apache.org/commons/latka/index.html) è un componente molto interessante ed è da sperare che una versione definitiva (attualmente siamo ancora in una fase alpha) sia disponibile a breve. Si tratta di uno strumento di test, implementato in Java, che utilizza la sintassi XML per definire una serie di richieste HTTP (o eventualmente HTTPS) e di regole di validazione, successivamente utilizzate per verificare che le richieste vengano processate correttamente da una applicazione web.

L'ultimo componente del gruppo, Commons EL (http://jakarta.apache.org/commons/el.html) è, a dire il vero, un po' più particolare, in quanto si tratta dell'interprete dell'"Espression Language" che fa parte delle specifiche 1.0 delle Java Standard Tag Libraries (JSTL). Una parte di queste specifiche sono state redatte, da parte di Sun, anche grazie all'aiuto fornito dal gruppo Jakarta che sta da tempo portando avanti un progetto contenente una serie di librerie di custom tag, chiamato "Taglibs". All'interno di questo progetto è presente l'implementazione Jakarta delle JSTL. Il componente EL ne è il naturale completamento.

 

Altri componenti
L'ultimo gruppo è, come spesso succede, molto generico e senza un vero e proprio filo conduttore. Non è, infatti, molto semplice inserire i tre componenti, Codec, Discovery e Modeler all'interno di una delle precedenti categorie, proprio a causa delle loro peculiarità.

Commons Codec (http://jakarta.apache.org/commons/codec/index.html) è nato con l'intento di fornire le implementazioni di alcuni tra i più diffusi sistemi di codifica e decodifica, come Base64, Hex ed URL, quello utilizzato dal protocollo HTTP. Col trascorrere del tempo, però, altri sviluppatori hanno cercato di sfruttare il più possibile il codice già presente per costruire un framework dove poter sviluppare altri sistemi come quelli utilizzati, ad esempio, dalla fonia.

Commons Discovery (http://jakarta.apache.org/commons/discovery.html) è un componente piuttosto particolare, pensato con l'intento di sviluppare un sistema per cercare, trovare e scoprire implementazioni per interfacce. L'idea deriva in parte dall'esperienza maturata su questo argomento durante lo sviluppo di Commons Logging, e in parte dalla consapevolezza che non esiste ancora alcuna soluzione comune e standard al problema.

La funzione dell'ultimo componente del gruppo è strettamente connessa alle JMX (Java Management eXtensions) API di Sun, tramite le quali è possibile costruire applicazioni per la configurazione di applicazioni server. Il cuore di queste API è il Management Bean, (MBean) che, però, richiede un lungo lavoro di preparazione. Commons Modeler (http://jakarta.apache.org/commons/modeler.html) è stato sviluppato per rendere questa operazione più semplice, principalmente attraverso l'uso di un documento in formato XML per ogni MBean da costruire, oltre che ad alcuni strumenti per snellire le operazioni di supporto.

 

Conclusioni
Come spesso accade con i progetti del gruppo Jakarta, anche per Commons si nota in modo evidente la volontà di costruire una soluzione riutilizzabile, non solo per gli altri progetti del gruppo, ma anche e soprattutto per l'intera comunità. Ma non ci si ferma qui, visto che alcuni componenti sono chiaramente stati pensati per sopperire ad alcune mancanze del linguaggio e, quindi, si propongono a Sun come nuove idee. Il gruppo, da questo punto di vista, ha una lunga storia di successi...

 

Risorse
La pagina principale del progetto, http://jakarta.apache.org/commons, contiene tutti i link per accedere alle homepage di ogni singolo componente, da dove è poi possibileraggiungere le differenti pagine di download. Come per tutti i progetti Jakarta, infatti, è possibile ottenere sia i sorgenti, la sola versione compilata, le prerelease (alfa e beta) oppure le "nightly build", ossia le versioni che vengono ricompilate ogni sera e la cui qualità non è assolutamente garantita.


Figura 3
- La pagina che raccoglie i link per i download dei vari componenti

Esiste anche una pagina che raccoglie i link per il download di tutti i componenti, differenziati per stato (rilasciati, in sviluppo e Sandbox), che personalmente ritengo più utile e comoda per tenere sotto controllo lo stato dei vari componenti.

 

Bibliografia
[1] Vikram Goyal - "Using the Jakarta Commons", OnJava.com, 2003

MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it