Non solo J2EE

download Non solo J2EE

of 8

Transcript of Non solo J2EE

  • 8/3/2019 Non solo J2EE

    1/8

    CP pensareprogettareprogrammare n. 136 giugno 2004

    Non solo J2EEdi Giorgio Maone

    LApplication Server fornisce utilissimi servizi a chi sviluppa in Java, ma larchitettura J2EE econsiderata, almeno per alcuni aspetti, complicata e pesante: siamo pronti per i LightweightContainer?

    Giorgio Maone

    E responsabile tecni-co per larea svilupposoftware di InformAc-tion, societa di con-sulenza che dirige dal1998. Si occupa di so-luzioni multi-tiered supiattaforme EnterpriseJava (J2EE) e Micro-soft (.NET), di produ-zioni multimediali e diformazione negli am-biti Web, middle-tier,DB e multimedia.

  • 8/3/2019 Non solo J2EE

    2/8

    pubblicato suWWW.INFOMEDIA.IT

    stampa digitale da

    Lulu Enterprises Inc.

    stores.lulu.com/infomedia

    Infomediamedia e limpresa editoriale che da quasi venti an-

    a raccolto la voce dei programmatori, dei sistemi-

    dei professionisti, degli studenti, dei ricercatori e dei

    essori dinformatica italiani.

    o piu di 800 gli autori che hanno realizzato per le te-

    Computer Programming, Dev, Login, Visual Basic

    nal e Java Journal, molte migliaia di articoli tecnici,

    entazioni di prodotti, tecnologie, protocolli, strumen-lavoro, tecniche di sviluppo e semplici trucchi e stra-

    mmi. Oltre 6 milioni di copie distribuite, trentamila

    ne stampate, fanno di questa impresa la piu grande ed

    ente realta delleditoria specializzata nel campo della

    rammazione e della sistemistica.

    tti questi anni le riviste Infomedia hanno vissuto del-

    assione di quanti vedono nella programmazione non

    la propria professione ma unattivita vitale e un vero

    rtimento.

    2009, Infomedia e cambiata radicalmente adottando

    uovo modello aziendale ed editoriale e si e organiz-

    attorno ad una idea di Impresa Sociale di Comunita,

    ecipata da programmatori e sistemisti, separando le

    ita di gestione dellinformazione gestite da un board

    unitario professionale e quelle di produzione gesti-

    a una impresa strumentale. Questo assetto e in linea

    le migliori esperienze internazionali e rende Infome-

    ancora di piu parte della Comunita nazionale degli

    uppatori di software.

    media e media-partner di manifestazioni ed eventi in

    ito informatico, collabora con molti dei pi u impor-

    editori informatici italiani come partner editoriale e

    itore di servizi di localizzazione in italiano di testi in

    ua inglese.

    aginazione automatica di questa rivista e realizzata al

    % con strumenti Open Source usando OpenOffice,

    cs, BHL, LaTeX, Gimp, Inkscape e i linguaggi Lisp,

    hon e BASH

    copyright information about the contents of Compu-

    Programming, please see the section Copyright at

    end of each article if exists, otherwise ask authors.media contents is 2004 Infomedia and released as

    ative Commons 2.5 BY-NC-ND. Turing Club content

    2004 Turing Club released as Creative Commons

    BY-ND.

    nformazioni di copyright sul contenuto di Computer

    gramming sono riportate nella sezione Copyright

    fine di ciascun articolo o vanno richieste direttamen-

    gli autori. Il contenuto Infomedia e 2004 Infome-

    e rilasciato con Licenza Creative Commons 2.5 BY-

    ND. Il contenuto Turing Club e 2004 Turing Club

    asciato con Licenza Creative Commons 2.5 BY-ND.

    pplicano tuttele normedi tuteladeimarchie deisegni

    ntivi.

    ogni caso ammessa la riproduzione parziale o tota-

    ei testi e delle immagini per scopo didattico purche

    gano integralmente citati gli autori e la completa

    tificazione della testata.

    oscritti e foto originali, anche se non pubblicati, non

    stituiscono.

    tenuto pubblicitario inferiore al 45%.

    biografia dellautore riportata nellarticolo e sul

    www.infomedia.it e di norma quella disponibi-

    nella stampa dellarticolo o aggiornata a cu-

    dellautore stesso. Per aggiornarla scrivere a

    @infomedia.it o farlo in autonomia allindirizzo

    //mags.programmers.net/moduli/biografia

    http://www.infomedia.it/http://stores.lulu.com/infomediahttp://stores.lulu.com/infomediahttp://stores.lulu.com/infomediahttp://stores.lulu.com/infomediahttp://www.infomedia.it/
  • 8/3/2019 Non solo J2EE

    3/8

    Da qualche tempo la comunit degli sviluppatori Java cosiddetti enterprise in fermento. Laparola dordine sembra essere semplicit, e inmolti iniziano ad esplorare percorsi alternativi

    alla piattaforma Java 2 Enterprise Edition tradizionalmen-te intesa. Nessuno mette in discussione le tecnologie fon-

    danti, come Servlet o JDBC, ma linsofferenza da pi partimanifestata fin dalla loro comparsa verso astrazioni dilivello pi alto (leggi EJB), si concretizza adesso in propo-ste variamente convincenti ma quantomeno tangibili. Cisi deve, almeno in parte, allattenzione che ormai riscuotelAspect Oriented Programming(AOP), non pi considerataspeculazione teorica bens strumento pratico e, in quantotale, valutabile e sfruttabile in termini pragmatici.SullAOP e sul principio non nuovissimo dellInversion ofControl, o pi propriamente sulla sua specializzazione chia-mata Dependency Injection, si basano alcuni frameworkapplicativi che ambiscono a sostituire la monoliticitdellApplication Server con un approccio modulare e noninvasivo, teso a cucire insieme i componenti eterogeneidi unapplicazione riducendo le dipendenze esplicite, alloscopo di assicurare massima libert nelle scelte implemen-tative.

    Prima di indagare le nuove tendenze, per opportunofare brevemente il punto su ci che oggi J2EE rappresentaed offre.

    Quel che passa il conventoLhome page di J2EE [1] riassume le varie sfaccettature

    dellarchitettura raggruppandole come segue:

    Tecnologie per i Web Service Java API for XML Processing (JAXP)

    Java API for XML Registries (JAXR) Java API for XML-based RPC (JAX-RPC) SOAP with Attachments API for Java (SAAJ)

    Tecnologie per lo sviluppo orientato ai componenti Java Servlet JavaServer Pages (JSP) JavaServer Faces (JSF) Enterprise JavaBeans (EJB) Java Message Service (JMS) J2EE Connector Architecture (JCA)

    Tecnologie per la gestione della piattaforma J2EE Deployment Specification J2EE Management Specification J2EE Client Provisioning Java Authorization Contract for Containers

    Altre tecnologie

    Java DataBase Connectivity (JDBC) Java Data Objects (JDO) JavaMail Infrastruttura transazionale, cio Java Transaction

    API (JTA) e Java Transaction Service (JTS)

    Come si vede, gli EJB spesso considerati la tecnologia J2EE per antonomasia non sono che una tessera in unmosaico ricco e articolato: nessuno vieta di scrivere appli-cazioni J2EE facendone a meno.

    Molti progetti si basano effettivamente sullaccoppiataServlet Container/JDBC e saltano a pi pari i livelli inter-medi, magari con laiuto di un framework MVC comeStruts e adottando il pattern DAO per non sporcaretroppo il controller. Cionondimeno, gli EJB costituisconoun modello a componenti robusto, consolidato e prevedi-bile, che mostra allo sviluppatore un sentiero da seguiresenza eccessivi sforzi di fantasia per partizionare lapplica-zione ed usufruire gratuitamente di servizi indispensabi-li per progetti medio-grandi:

    gli Entity Bean rispecchiano le entit persistenti e lerelazioni che tra esse intercorrono, e sono essenzial-mente oggetti Java che vivono nel database, salvati erecuperati in maniera transazionale e trasparente(almeno quelli di tipo CMP);

    i Message-Driven Bean reagiscono ad eventi scatenati da

    messaggi accodati tramite JMS, e rappresentano la viaufficiale alla programmazione asincrona, visto che lEJBcontainer proibisce il multi-threading esplicito;

    i Session Bean, infine, ospitano la logica applicativa,demarcano i confini delle transazioni (in modo dichia-rativo o programmatico) ed interagiscono con altri EJBe con i client.

    In definitiva, i principali vantaggi ideali di unapplica-zione composta da EJB sono:

    dislocazione dei componenti, che rispetto ai client pos-sono essere locali (residenti nella stessa JVM) o remoti(anche su unaltra macchina);

    persistenza indipendente dal tipo di DBMS e dalluso diSQL, poich gli Entity Bean sono una forma diObject/Relational Mapping(ORM) e consentono al pro-grammatore di lavorare su oggetti tipizzati piuttosto chesu ResultSet generici;

    22 Computer Programming n. 136 - Giugno 2004

    FOCUS

    Non solo J2EELApplication Server fornisce utilissimi servizi a chi sviluppa in Java, ma larchitettura J2EE considerata,

    almeno per alcuni aspetti, complicata e pesante: siamo pronti per i Lightweight Container?

    di Giorgio Maone

    Giorgio Maone

    responsabile tecnico per larea sviluppo software di InformAction,societ di consulenza che dirige dal 1998. Si occupa di soluzionimulti-tiered su piattaforme Enterprise Java (J2EE) e Microsoft (.NET),di produzioni multimediali e di formazione negli ambiti Web, midd-le-tier, DB e multimedia.

    [email protected]

  • 8/3/2019 Non solo J2EE

    4/8

    caching e pooling, dal momento che tutti gli accessi aidati avvengono attraverso lApplication Server (persi-stenza container managed) e che questultimo, pertanto,pu decidere cosa trattenere in memoria e quando,invece, il caso di scomodare il database;

    demarcazione dichiarativa delle transazioni, che sono

    in grado di propagarsi tra diversi metodi e coinvolgererisorse eterogenee (transazioni distribuite XA); sicurezza a livello di metodo (prima di eseguire una

    chiamata il container verifica che il chiamante abbiaprivilegi sufficienti).

    Daltra parte, com noto, gli EJB sono soggetti a durecritiche. Alcune, per cos dire storiche, riguardanosoprattutto la quantit di codice necessaria a scriverli econfigurarli nonch le performance non proprio brillanti.Al primo problema si pu ovviare adottando strumenti digenerazione del codice, mentre le prestazioni sensibil-mente migliorate con lintroduzione delle interfacce loca-li e la conseguente riduzione delle chiamate a metodo

    remoto dipendono molto dalla qualit dellApplicationServer, dalla bont della sua configurazione e, ovviamen-te, dallaccortezza del programmatore. Le obiezioni pisolide, invece, vertono sulleccessiva invasivit dellAPI(interfacce da implementare e classi da estendere che ren-dono difficoltoso il riuso in altri contesti) e sulle rigiditdegli Entity Bean come strumento ORM (granularit, ere-ditariet, relazioni, linguaggio di interrogazione).Parliamo quindi di criticit strutturali, che inducono abattere strade diverse verso unarchitettura J2EE privadegli EJB ma provvista dei vantaggi ad essi tradizional-mente associati.

    La doppia vita di JBoss, leretico

    JBoss [2] , oggi, il pi popolare Application Server Java.Trattandosi di un progetto open source (LGPL), gestito dasviluppatori J2EE che si confrontano quotidianamente coni limiti della piattaforma, la sua evoluzione riflette gliumori della base ed anticipa le nuove tendenze, inclusaquella che vorrebbe un ridimensionamento degli EJB eduna maggiore libert di scelta. La serie stabile 3.2.x costi-tuisce una (eccellente) implementazione classica, attual-mente in attesa della certificazione J2EE da parte di Sun. Ildesign fortemente modulare:

    alla base, un microkernel ridotto al minimo forniscelinfrastruttura di base per il classloading dinamico,

    lhot deployment di componenti e la gestione tramiteinterfaccia JMX; i servizi di medio livello (Web Server, transaction

    manager, security manager, gestori della persistenza,della cache, del clustering ecc.) sono nettamente divisitra loro e ciascuno di essi racchiuso in un ServiceARchive (SAR), che si pu aggiungere, rimuovere osostituire a piacimento;

    i componenti applicativi, e segnatamente gli EJB,acquisiscono i comportamenti implementati dai servizi(transazionalit, persistenza, controlli di sicurezza) tra-mite wrapper chiamati Interceptor, che si frappongono aruntime tra il componente ed il suo utilizzatore.

    Gli Interceptor, in quanto mezzo per aggiungere dinami-camente comportamenti di interesse generale ad oggettiche implementano logiche applicative, rappresentavanogi dalla versione 2 di JBoss un elemento di AspectOriented Programming ante litteram. Non stupisce che

    oggi, essendo la riflessione sullAOP maturata giungendo aun buon livello di formalizzazione, si voglia offrire allo svi-luppatore finale la possibilit di intervenire in modo sem-plice e selettivo sul processo di intercettazione. Lo scenarioprospettato da JBoss 4 il ramo attualmente in fase di svi-luppo affascinante: lapplicazione vera e propria com-

    posta da Plain Old Java Objects (POJO), vale a dire comu-nissimi oggetti Java a cui non sono prescritte interfacce olinee ereditarie particolari (in contrasto con gli EJB), e quin-di in generale riutilizzabili anche fuori dallApplicationServer. Aspetti come la persistenza, la transazionalit, lin-vocabilit remota, la sicurezza ecc. vengono specificati attra-verso metadati esterni (descrittori XML) o interni al codice(speciali commenti JavaDoc o, in futuro, le annotationsintrodotte da J2SE 1.5): il framework JBossAOP li appli-cher magicamente al momento del deployment. Questoapproccio si traduce, per la gioia di molti, in un J2EE senzaEJB che mantiene intatta la sua potenza di fuoco.Ciononostante, il supporto per gli EJB sar conservato,anche se ovviamente limplementazione interna degli stes-

    si far leva sullo strato AOP. Non si tratta solo di una scel-ta politica tesa a preservare la compatibilit con le appli-cazioni e i componenti esistenti: ladesione di JBoss Inc.allEJB Expert Group, annunciata il 5 aprile scorso, induceviceversa a sperare in una specifica EJB 3.0 pi leggera,semplice e potente che tesaurizzi lesperienza accumulatadal progetto open source.

    Persistenza alternativa: HibernateQualche lettore si sar gi chiesto come far JBoss 4 a

    rendere dinamicamente persistenti su database i POJOche, per definizione, non sono vincolati allimplementa-zione di interfacce particolari n sono obbligati a discen-dere da classi di un determinato framework. La risposta Hibernate [3], un maturo strumento ORM open sourceche vanta, tra le sue caratteristiche specifiche, proprio ilbasso tasso di intrusione e prescrizione rispetto agli ogget-ti da esso gestiti. Questa la principale motivazione chespinge una vasta platea di sviluppatori a preferirlo rispettoa soluzioni standard come Entity Bean e soprattutto alladiretta concorrenteJava Data Objects (JDO) [4], specificaufficiale per la persistenza degli oggetti Java. A cercare ilpelo nelluovo, si pu obiettare che le tre tecnologie, piche in competizione, sarebbero potenzialmente comple-mentari, nellipotesi che gli Entity Bean utilizzino inter-namente Hibernate (come avverr in JBoss 4) e che, a suavolta, Hibernate implementi in futuro le interfacce JDO,

    congettura corroborata dalla presenza dellautore, GavinKing, nel JDO 2.0 Expert Group. Restando ai fatti, permappare su un database relazionale oggetti Java conHibernate sufficiente specificare alcuni metadati, mancoa dirlo in formato XML, che possono essere centralizzati inun unico file di configurazione (come avviene con gli EJB)oppure divisi per package o per classe (opzione consigliataperch facilita il riuso). Tale incombenza enormementealleviata da XDoclet [5], strumento per la programmazio-neAttribute Oriented di cui ci siamo gi occupati [6]: esso,attraverso un apposito task Ant chiamato HibernateDoclet ,provvede automaticamente a generare i descrittori dimapping a partire da sorgenti commentati con particolaritag JavaDoc. Il Listato 1, ad esempio, si riferisce ad unen-

    tit che rappresenta una localit italiana. Il tag hiberna-te.class segnala che la classe deve essere mappata sul data-base, mentre con hibernate.property si contrassegnano lepropriet persistenti. indispensabile individuare una opi propriet, marcate con hibernate.id, come identificati-

    Computer Programming n. 136 - Giugno 2004 23

    Application Server

  • 8/3/2019 Non solo J2EE

    5/8

    FOCUS

    vo univoco che si tradurr in una primary key. Ad esplici-tare la relazione molti a uno intercorrente tra la pro-prietprovincia e lomonima classe, anchessa mappata, iltag hibernate.many-to-one, che in questo caso specificaanche la colonna da usare come foreign key.Unapplicazione che usa Hibernate innanzitutto configura

    un oggetto SessionFactory indicando, tra laltro, i mappingda usare e i parametri di connessione al DB.

    La factory sar in seguito utilizzata per ottenere oggettiSession, che sono linterfaccia principale per il dialogo conil motore di persistenza. Il codice Java per istanziare un

    oggetto Localita (Monreale, in provincia di Palermo) e sal-varlo sul database potrebbe essere:

    net.sf.hibernate.SessionFactory factory;

    // omessa configurazione preliminare

    // della SessionFactory

    [...]net.sf.hibernate.Session session = factory.getSession();

    Localita monreale = new Localita();

    monreale.setDes(Monreale);

    monreale.setCap(90046);

    monreale.setPrefisso(091);

    // recupera un oggetto Provincia tramite ID

    Provincia palermo =

    (Provincia)session.get(Provincia.class, PA);

    monreale.setProvincia(palermo);

    session.save(monreale); // salva la localit

    session.flush(); // sincronizza il database

    Un punto di forza di Hibernate il suo linguaggio di

    interrogazione Hibernate Query Language (HQL), che risul-ta spesso molto pi espressivo dello stesso SQL, e comun-que di gran lunga pi potente di EJBQL. Ecco, ad esempio,la query HQL che genera un report con il conteggio dellelocalit appartenenti a ciascuna provincia, raggruppando itotali per regione:

    select localita.provincia.regione.des,

    localita.provincia.des, count(localita)

    from Localita localita

    group by 1, 2

    Hibernate la tradurr pressappoco nella seguente join SQL:

    select regione.des,

    provincia.des, count(localita.id)

    from localita, provincia, regione

    where localita.id_prov=provincia.id

    and provincia.id_reg=regione.id

    and localita.id_prov=provincia.id

    group by 1, 2

    LAPI Criteria permette, inoltre, di impostare dinamica-mente i criteri di ricerca in maniera object oriented, piut-tosto che esprimerli sotto forma di stringhe, e supporta lecosiddette query by example, cio la ricerca di oggetti chesomigliano ad un certo modello. Viceversa, nei rari casi

    in cui non c alternativa, si possono eseguire query SQL abasso livello tramite Hibernate (che provveder comun-que a mappare i risultati), oppure recuperare lajava.sql.Connection utilizzata dalla Session corrente e opera-re direttamente tramite JDBC. Dulcis in fundo, il tool inte-rattivo Hibern8IDE (Figura 1) aiuta a testare query HQL ecodice Java (o, pi precisamente, BeanShell) nel contestodi Hibernate.

    Chiamare le cose con il loro nome

    Facciamo un passo indietro: curiosamente, al momentoin cui scriviamo, la gi citata home page di J2EE non men-ziona la Java Naming and Directory Interface (JNDI) [7];essa, tuttavia, assume nellarchitettura un ruolo centrale di

    collante, tenendo insieme i componenti e i servizi ospitatidallApplication Server. Le applicazioni, infatti, ottengonoriferimenti alle risorse gestite dal container (EJB, code dimessaggi, DataSource JDBC, UserTransaction JTA ecc.)attraverso un procedimento simile al seguente:

    24 Computer Programming n. 136 - Giugno 2004

    LISTATO 1 La classe Localita, unentit persistentescritta come un normale JavaBean e annotatacon i tag XDoclet per Hibernate

    package com.informaction.geo.model;

    /*** @hibernate.class*/

    public class Localita {

    private Integer id;private String des;private String cap;private String prefisso;private Provincia provincia;

    public Localita() {}

    /*** @hibernate.id generator-class=identity*/public Integer getId() {return id;

    }public void setId(Integer id) {this.id = id;

    }

    /*** @hibernate.property*/public String getDes() {return des;

    }public void setDes(String des) {this.des = des;

    }

    /*** @hibernate.property*/public String getCap() {

    return cap;}public void setCap(String cap) {this.cap = cap;

    }

    /*** @hibernate.property*/public String getPrefisso() {return prefisso;

    }public void setPrefisso(String prefisso) {this.prefisso = prefisso;

    }

    /*** @hibernate.many-to-one* column=id_prov not-null=true*/public Provincia getProvincia() {return provincia;

    }public void setProvincia(Provincia provincia) {this.provincia = provincia;

    }}

  • 8/3/2019 Non solo J2EE

    6/8

    import javax.naming.*;

    import javax.sql.*;

    public class DataManager {

    private NamingContext ctx =

    new InitialContext();

    private DataSource dataSource =

    (DataSource)ctx.lookup(jdbc/mainDS);

    [...]

    }

    Nellesempio la classe DataManager recupera dal conte-sto JNDI (NamingContext) una sorgente dati tramite ilnome simbolico jdbc/mainDS, al quale lamministratoredel server lavr precedentemente associata intervenendosu un file di configurazione oppure operando su una GUI(laddove disponibile).

    Il codice lavora sullinterfaccia DataSource, la cui imple-

    mentazione concreta varier a seconda del tipo di databa-se, delleventuale gestione del pooling, del supporto pertransazioni distribuite (XA) ecc. Lo scenario non dissi-mile da quello che, sotto Windows, riguarda ODBC: ilsistemista configura una sorgente di dati particolare asso-ciandole un nome (DSN), che il programma sfrutter percercarla ed utilizzarla secondo uninterfaccia uniforme.JNDI, tuttavia, generalizza il paradigma:

    consente di registrare (bind) e recuperare (lookup) risor-se di ogni tipo (oggetti di qualunque classe, anche defi-nita dallutente);

    una tecnologia distribuita, basata di serie su RMI,LDAP o CORBA ma estensibile con altri protocolli;

    offre supporto esplicito, tramite linterfacciajavax.naming.spi.ObjectFactory, per la creazione dina-mica delle istanze richieste.

    I benefici evidenti sono:

    disaccoppiamento dellimplementazione dei servizi daiclient, che ne conoscono solo le interfacce;

    trasparenza di posizione (un oggetto pu essere remo-to, cio risiedere fisicamente su un elaboratore diversoda quello del client, senza che la procedura di lookupcambi);

    intercettabilit tramite metodo factory, che consentedi scegliere unimplementazione particolare, decoraree/o configurare loggetto prima di fornirlo allutilizza-tore.

    Un effetto collaterale non trascurabile, daltro canto, il

    proliferare del codice di lookup un po dovunque, che sitraduce in una forte dipendenza dellapplicazione dallin-frastruttura e, di conseguenza, in pesanti difficolt nel riuti-lizzare componenti al di fuori dellApplication Server, spe-cie in unapplicazione desktop disconnessa o, comunque,in assenza di un server JNDI. Tale problema pu esseremitigato dalladozione del pattern Service Locator [8], cheaiuta a centralizzare, schermare e ottimizzare gli accessi alservizio di Naming. Tuttavia, anche nellipotesi di sostitui-re limplementazione JNDI di un Service Locator con unaversione in grado di fare a meno del container J2EE, comeconfigurarla? Una possibile soluzione viene dai frameworkbasati sulla Dependency Injection.

    Inversione, che invenzione!Lespressione Inversion of Control (IoC) si riferisce a un

    concetto descritto in maniera sintetica quanto efficace daMichael Mattson gi nel 1996:

    La principale differenza tra un framework orientato aglioggetti ed una libreria di classi che il framework chiama il codi-ce dellapplicazione. Normalmente il codice dellapplicazionea chiamare la libreria di classi. Questa inversione di control-lo chiamata, a volte, il principio di Hollywood, ovveroNon chiamarci, chiameremo noi. [9]

    Si tratta di uno stile adottato, pi o meno consapevol-mente, da ogni programmatore OOP diligente, anche per-ch aiuta a rispettare unaltra regola di corretto design, ilDepency Inversion Principle (DIP) enunciato da Robert zioBob Martin [10]:

    I moduli ad alto livello non devono dipendere dai moduli abasso livello. Gli uni e gli altri devono dipendere da astrazioni.

    Le astrazioni non devono dipendere dai dettagli. I dettaglidevono dipendere dalle astrazioni.

    In parole povere (e in linguaggio Java): programmare perinterfacce...

    LIoC, se non in teoria almeno in pratica, una delleprime cose su cui sbatte il naso un programmatore Java.

    Qualunque sia la tua specialit dalleApplet alle Servletfino agli EJB ti abitui allidea di un contenitore (il brow-ser o il server) che invoca i metodi dei tuoi oggetti, solita-mente per controllarne il ciclo di vita. Questa forma diIoC, secondo la quale le classi che compongono unappli-cazione implementano una o pi interfacce note, dandocos modo al framework di chiamarle, stata a lungo lu-nica teorizzata ed particolarmente adatta per le architet-ture orientate ai servizi.

    La sfrutta J2EE, per quanto in maniera implicita e pocosistematica, mentre ne fa la sua colonna portante il progettoAvalon [11], una specie di meta-container che si candidacome infrastruttura per ogni sorta di server o di applicazionemodulare. Una delle aree nelle quali si sono evidenziati i

    benefici dellIoC la risoluzione delle dipendenze tra com-ponenti e servizi, o in altri termini lassemblaggio delleapplicazioni. Della soluzione standard, JNDI, abbiamo gidiscusso i pro e i contro. Lapproccio tipico di Avalon e diprogetti similari chiamato Contextual Lookup: il compo-

    Computer Programming n. 136 - Giugno 2004 25

    Application Server

    FIGURA 1 Hibern8IDE, un tool per testare interattivamentequery e codice Java in un contesto Hibernate

  • 8/3/2019 Non solo J2EE

    7/8

    nente specifica le proprie dipendenze in un file di configura-zione, e implementa uninterfaccia (Serviceable, nel caso diAvalon) attraverso la quale il container fornir un contestodi lookup personalizzato (ServiceManager) che consentirdi recuperare tutti gli oggetti necessari e solamente quelli.Tornando allesempio del DataManager che ha bisogno di

    una DataSource, esso andrebbe riscritto cos:

    import javax.sql.*;

    import org.apache.avalon.framework.*;

    public class DataManager implements Serviceable {

    private DataSource dataSource;

    public void service(ServiceManager sm) {

    dataSource =

    (DataSource)sm.lookup(dataSource);

    }

    [...]

    }

    Non sembra un gran progresso: il nostro componente non pi accoppiato a JNDI, ma dipende comunque daServiceable e da ServiceManager. Per di pi, riusare questocomponente in assenza di Avalon sembra alquanto farragi-noso: per configurarlo bisogna fornire unimplementazionealternativa di ServiceManager, riempirla e passarla al meto-do service(). Allimprovviso una mente brillante, rimuginan-do sulla faccenda, folgorata dallesistenza di uninterfacciaimplementata implicitamente dalla maggior parte deglioggetti Java e utilizzabile per configurare le dipendenze: i set-ter delle propriet. Sembra luovo di Colombo, al punto chesi ritiene di aver scoperto un nuovo tipo di IoC, il cosiddettoType 2, attorno al quale sar edificato Spring [12].

    La rivoluzione leggeraSpring un framework applicativo open source, modulare

    e non invasivo, basato su AOP e Dependency Injection.Iniezione delle dipendenze la designazione proposta daMartin Fowler [13] per deflazionare luso dellespressioneInversion of Control, il cui contenuto semantico andava sci-volando dal principio generale enunciato in [9] verso lac-cezione pi riduttiva di pattern impiegato per risolvere ledipendenze tra gli oggetti. Seguendo il consiglio di Fowler,non si parler pi di IoC Type 2 e IoC Type 3 bens,rispettivamente, di Setter Dependency Injection e Constructor

    Dependency Injection. Questultima, introdotta daPicoContainer [14], analizza il costruttore delloggetto perdedurne le dipendenze e tentare di soddisfarle al momentodella creazione. Una scuola di pensiero (a cui il sottoscrittoaderisce) tende a preferire tale procedura perch riduce ilrischio di trovarsi a maneggiare oggetti non correttamenteinizializzati, che Joshua Bloch chiamerebbe cattivi cittadi-ni. Adottando la Setter Injection, scelta predefinita inSpring, il DataManager si riscrive come un normale JavaBean, privo di dipendenze dal framework:

    import javax.sql.*;

    public class DataManager {

    private DataSource dataSource;

    public void setDataSource(

    DataSource dataSource) {

    this.dataSource = dataSource

    }

    [...]

    }

    La BeanFactory, cuore dellarchitettura di Spring, serve

    ad istanziare e collegare tra loro i diversi componenti (diservizio e applicativi) che formano lapplicazione, e puessere configurata in maniera programmatica o tramitelimmancabile descrittore XML. Il markup dellaBeanFactory semplice, ridotto allo stretto necessario percreare bean, assegnare loro un identificativo e popolarne lepropriet. Tornando a noi, innanzitutto dovremo prepara-re una DataSource:

    org.hsqldb.jdbcDriver

    jdbc:hsqldb:hsql://localhost:9001

    sa

    Si tratta di una BasicDataSource (cfr. [15]) che punta adun database HSQL e che chiamiamo semplicementedataSource. A questo punto possiamo dichiarare il nostroDataManager, iniettandogli la DataSource di cui sopra:

    In questo caso abbiamo risolto la dipendenza in manieraesplicita, indicando il nome della propriet e quello delbean da assegnarle.

    Spring, tuttavia, offre diverse opzioni di autowiring, cio

    di risoluzione automatica, tra le quali

    byName, che cerca tra i bean definiti nella factory quel-lo il cui id coincide col nome della propriet da valoriz-zare;

    byType, che invece cerca un bean il cui tipo sia tale darenderlo assegnabile alla propriet (funziona se c unoed un solo bean idoneo).

    Nel nostro esempio, essendoci una sola DataSource cheper di pi si chiama come la propriet, le varianti

    e

    26 Computer Programming n. 136 - Giugno 2004

    FOCUS

  • 8/3/2019 Non solo J2EE

    8/8

    si equivalgono. Spring, inoltre, supporta anche laConstructor Injection (altrimenti non lo userei). Quindi,supposto che DataManager preveda un costruttore siffatto:

    public DataManager(DataSource dataSource) {

    this.dataSource=dataSource;

    }

    si potr scrivere

    oppure, esplicitamente:

    Eliminando il setter ed il costruttore di default, ci si assi-curer cos che un DataManager sia sempre provvisto dellasua brava DataSource.

    La primavera Aspect OrientedSpring molto pi che un framework semplice e poten-

    te per configurare le applicazioni riducendo le dipenden-ze esplicite tra i componenti.

    Non a caso chiamato anche Lightweight Container,alludendo al fatto che fornisce un ambiente di esecuzioneparagonabile a quello di un Application Server J2EE, masenza compromettere la riusabilit dei componenti inaltri contesti e incoraggiando pratiche virtuose come laprogrammazione per interfacce. Incorpora infatti un sot-tosistema Aspect Oriented compatibile con le specifi-che pubblicate dalla AOP Alliance e abbinabile alla pro-grammazione per metadati tramite attributi che luten-te pu utilizzare per scopi specifici ma che d il meglio dis nel fornire, in maniera trasparente, servizi dinfrastrut-tura quali:

    demarcazione dichiarativa delle transazioni, sia localiche distribuite, sui metodi dei POJO;

    remoting basato su RMI e Web Service JAX-RPC oCaucho (protocolli Hessian e Burlap);

    gestione automatica delle sessioni di persistenza

    Hibernate.

    Per le applicazioni Web, il framework offre una sua inte-ressante proposta di MVC, ma anche un eccellente sup-porto per le tecnologie consolidate (JSP/JSF, Struts,Velocity) ed emergenti come Tapestry [17].

    Alcuni template dedicati facilitano e standardizzanolimplementazione di Data Access Object basati su JDBC,Hibernate, JDO o iBATIS [18]. Il criterio ispiratore , disicuro, la libert di scelta: a seconda delle necessit,Spring pu sostituire lApplication Server tradizionaleoppure collaborare proficuamente con esso. Nella secon-da ipotesi, semplifica luso degli EJB e permette di relega-re i lookup JNDI nella BeanFactory, coniugando cos i

    vantaggi del servizio di Naming standard con quelli dellaDependency Injection. Il design pulito e ben ripartito:le librerie di supporto che coprono aree non sovrappostesono archiviate in JAR separati e autonomi, in modo cheunapplicazione desktop, ad esempio, non debba portarsi

    dietro dipendenze inutili legate al Web-tier. Lestremaflessibilit di Spring e la sua discrezione (intesa comescarsa propensione ad intromettersi nel codice applicati-vo) sono le fondamenta della sua popolarit: al momentoin cui scriviamo, viaggia attorno agli 8.000 downloadmensili. La mia azienda lo sta adoperando per realizzare

    due versioni distinte della stessa applicazione: una desk-top con interfaccia utente Swing e database embedded(HSQLDB), laltra Web based (Tapestry) con RDMBSMySQL. Entrambe sfruttano Hibernate, ed il riuso delleclassi business, grazie alla Dependency Injection eallAOP, pressoch totale, a dispetto delle differenzeinfrastrutturali.

    ConclusioniQuanto scritto finora non vuole essere un manifesto con-

    tro J2EE: al contrario, i framework ed i principi illustrativanno considerati un approccio alternativo per combinaretra loro le valide tecnologie che compongono la piattafor-ma. Anche lo slogan J2EE senza EJB va preso con le

    dovute cautele: sarebbe un peccato disperdere il patrimo-nio di conoscenze accumulato da fior di sviluppatori sustrumenti che, se maneggiati con sapienza, produconorisultati egregi.

    Daltronde ci sono ottimi motivi per credere che la spe-cifica EJB 3.0 assorbir molti dei concetti fin qui esposti,dallAOP alla Dependency Injection passando per i meta-dati espressi in annotation: finalmente gli Enterprise JavaBean si programmeranno come i POJO. Se tutto va bene,dopo una gestazione lunga e travagliata, siamo vicini allanascita di J3EE, sotto il segno della semplicit.

    Computer Programming n. 136 - Giugno 2004 27

    Application Server

    BIBLIOGRAFIA & RIFERIMENTI[1] Home page di J2EE, http://java.sun.com/j2ee[2] Home page di JBoss, http://www.jboss.org[3] Home page di Hibernate, http://www.hibernate.org[4] Java Data Objects, http://java.sun.com/products/jdo[5] Home page di XDoclet, http://xdoclet.sourceforge.net[6] Gorgio Maone Sviluppo J2EE rapido con XDoclet,

    Computer Programming n. 122[7] Java Naming and Directory Interface,

    http://java.sun.com/products/jndi/[8] Service Locator Pattern, http://java.sun.com/blueprints/

    corej2eepatterns/Patterns/ServiceLocator.html[9] Michael Mattson, Object-Oriented Frameworks: a survey

    of methodological issues, PhD thesis, University College ofKarlskrona/Ronneby, 1996

    [10] Robert C. Martin, The Dependency Inversion Principle,C++ Report, 1996, http://www.objectmentor.com/resour-ces/articles/dip.pdf

    [11] Il progetto Avalon, http://avalon.apache.org[12] Home page di Spring, http://www.springframework.org[13] Martin Fowler - Inversion of Control Containers and the

    Dependency Injection pattern,http://martinfowler.com/articles/injection.html

    [14] PicoContainer, un framework basato su ConstructorInjection, http://picocontainer.org

    [15] Commons DBCP, libreria di classi per il connection pooling,http://jakarta.apache.org/commons/dbcp

    [16] Liniziativa AOP Alliance, http://aopalliance.sourcefor-

    ge.net[17] Tapestry, framework Web a componenti, http://jakarta.apa-che.org/tapestry/

    [18] iBATIS, framework per laccesso ai DB SQL,http://www.ibatis.com