In quest‘articolo si fa riferimento all‘organizzazione del lavoro di back-end, cioè quella preziosa attività che il pubblico non vede, ma che permette la circolazione di ciò che è fondamentale: il dato.
Introduzione
Nella prima parte di “Web applications in Java a basso costo di manutenzione” abbiamo parlato di un modo semplice di strutturare le web application. Questa volta proponiamo una “semplice” struttura client-server: una quantità di client Java, che contengono la maggior parte della logica di business, parlano con una servlet che si limita ad accedere al database, risparmiando quindi al client di sapere su che DBMS va, come è fatto, ecc.
Ma non l’avevano già inventato? Non funzionano così i web service? Andiamo con ordine.
La logica del back-end
Normalmente il back-end è realizzato con una quantità di web application, a cui si accede da una homepage contenente un menù; questa rimanda direttamente alle varie applicazioni. In alternativa, talvolta ci si dimentica del vecchio motto “divide et impera”, che invece è basilare nella teoria degli algoritmi, e si mette su un’unica, massiccia, applicazione che fa tutto. Poi quando la si deve mettere in manutenzione… son dolori.
Pro e contro delle web application
I vantaggi di usare una web application sono i seguenti:
- niente da installare: quindi niente controllo sistemistico sui permessi per installare, specialmente in ambienti come Windows, e niente assistenza tecnica all’installazione;
- portabilità sui diversi browser e sistemi operativi, anche se non è assoluta, perche’ ciò richiede determinate attenzioni al momento del progetto;
- familiarità della grande maggioranza delle persone nei confronti dell’interfaccia web.
- possibilità di avere un help in linea, anche se non sempre contestuale.
Ma alcuni problemi rimangono:
- se devo fare un’elaborazione che richiede minuti, se non ore (perche’ devo elaborare oggetti la cui quantità è un numero di 4 o più cifre) devo curare molto attentamente il timing dell’application server;
- nella medesima situazione, devo prevedere il crash recovery;
- nella medesima situazione, l’operatore non ha alcun “feeling” del carico di lavoro a cui è sottoposto in quel momento il server, quindi non ha idea di quanto tempo occorrerà per terminare l’elaborazione; e potrebbe scambiare un tempo troppo lungo con un crash, che invece, non esisteva proprio.
Una soluzione
La soluzione alternativa proposta da questo articolo si inquadra in uno scenario preciso.
- parliamo della lavorazione di back-end, supporto a un importante servizio offerto mediante Internet al cliente, o in generale al pubblico;
- parliamo di un back-end effettuato nell’intranet, quindi all’interno della stessa azienda che espone i dati, o almeno collegata ad essa con tutti i criteri di sicurezza;
- parliamo di un back-end notevolmente articolato, affidato a operatori con responsabilità differenziate e codificate, ma che non richiede una particolare professionalità tecnica.
Descrizione
Andiamo diretti al centro: è una struttura, realizzata in Java, in cui i client sono pesanti, mentre il server è leggero. Non è per fare bastian-contrario: il sistema proposto non è solo una teoria, ma un prodotto realizzato con soddisfazione e successo per un progetto a visibilità nazionale. In alto a destra è possibile eseguire il download di uno ZIP allegato, contenente le classi più importanti del progetto.
Servlet
La struttura è composta di una servlet, il cui unico compito è quello di accedere al DB. Essa riceve semplicemente una di queste 3 richieste:
- un’apertura di una sessione, a cui ovviamente segue una valutazione delle credenziali per l’accesso;
- una query SQL; in caso di update o insert, eventualmente corredata di un array di stringhe per l’uso di prepared statement; e di un array di BLOB, classe javax.sql.rowset.serial.SerialBlob;
- un chiusura di sessione.
Alla 1a e alla 3a richiesta, la servlet risponde con un acknowledge, composto di pochi parametri. Alla richiesta della query, la esegue e, se si tratta di una select, restituisce i dati in una struttura che permette di mantenere la massima genericità, e cioè una matrice bidimensionale di oggetti Object.
Più in dettaglio: restituisce un oggetto it.stradaazzurra.vigna.Tabella; questo contiene un array (classe ArrayList) di righe it.stradaazzurra.vigna.Riga, a loro volta contenenti un array di Object e un array di SerialBlob; la tabella contiene inoltre alcuni metadati, cioè i nomi e i tipi delle colonne.
La prima cosa evidente è che così non è possibile scorrere il ResultSet amministrando l’accesso al DB; il client non vede alcun ResultSet, perche’ riceve la totalità dei dati in un’unica soluzione.
La servlet journalizza su una apposita tabella di DB tutto ciò che gli viene chiesto, senza che il client glielo chieda, insomma senza che ne sappia niente; allo stesso modo non sa con quale DBMS ne’ con quale DB sta parlando; l’unica cosa che deve conoscere è la tabella di cui ha bisogno e la sua struttura. Il lavoro della servlet è secco: riceve la richiesta, la serve, poi chiude. Dunque non è implementato un oggetto Session, anche se ovviamente l’application server lo crea. La sessione, invece “persiste” sul DB.
Client
Alla servlet si connettono i client. Questi sono applicazioni Java stand-alone, con interfaccia grafica di tipo Swing (l’AWT è stato scartato perche’ la portabilità non è al 100%). Devono essere più “magri” possibile, senza preoccuparsi che non siano troppi. Fino a circa 20 applicazioni, una normale impiegata o impiegato riesce a ricordarsi benissimo quale deve chiamare per fare una certa cosa. Se poi sono stati scelti dei bei colori, adatti ed “evocativi”, la memoria è ancora più aiutata. Se poi racchiudiamo tutto in una shell, sempre un client dello stesso tipo, che possiede solo il menù e si limita a chiamare tutti gli altri client, ciascuno come applicazione stand-alone, non devi nemmeno ricordarti quale chiamare. Il client apre la sessione, imposta le query, e ottiene un codice di ritorno che, se uguale a zero, è accompagnato dalla matrice di oggetti Object. Ciascun dato atomico dovrà essere castato, ma non è prolematico, anche perche’ i metadati fanno comunque parte del pacchetto restituito.
I client e le tabelle di servizio
Affinche’ tutta la baracca funzioni, oltre alla servlet, due client sono indispensabili; ma una volta fatti, sono identici per tutti i successivi progetti in cui si vuole usare il sistema.
Client di gestione account
Il primo è per la gestione degli accounts. Manovrerà 3 tabelle di DB: operatori, applicazioni e autorizza. Il loro compito è ovvio; la permission per ciascuna applicazione, poi, si può limitare solo a certe funzionalità.
Nello zip allegato sono state messe le DDL, in riferimento a un DBMS DB2, delle suddette 3 tabelle, e inoltre delle tabelle journal e sessioni; quest’ultima registra tutte le aperture e chiusure delle applicazioni.
Client di gestione aggiornamenti
Il secondo client necessario è per la gestione degli aggiornamenti: questo è un punto chiave, altrimenti il sistema perde di efficienza. Siamo abituati a pensare ai client java come a programmini che fanno task molto mirati, che si scaricano dalla rete e si eseguono in un paio di clic. Ma se abbiamo detto che i client possono essere anche molto pesanti, e poi che saranno soggetti a manutenzione frequente, è corretto usare Java WebStart e chiedere all’utente di scaricare dalla rete n JAR tutte le volte che ne ha bisogno? D’accordo, nelle ultime versioni il JNLP è notevolmente migliorato; però i forum sono pieni di gente che chiede aiuto perche’ qualcosa in JNLP non funziona; il problema è che il bacino d’utenza è limitato.
La soluzione è non usare Java WebStart, ma mettere tutti i JAR su una tabella di DB, che già abbiamo chiamato applicazioni, in una colonna di tipo BLOB. È una soluzione originale, in Italia comunque poco usata. Ogni client, dopo essersi autenticato con successo, va a vedere se in tabella sono presenti versioni più recenti di se’ stesso e di tutti i JAR collegati. Se qualcuno è più recente, lo scarica, poi chiude e chiede una nuova apertura all’operatore. Il meccanismo è basato sul Manifest.mf, un file prezioso che, è bene ricordarlo, si può configurare anche con lo stesso task Ant che impacchetta il JAR.
Questo secondo client, dicevamo, gestisce gli aggiornamenti caricando sul DB le nuove versioni dei JAR. Mentre con Java Web Start, per caricare, cioè pubblicare una nuova versione, devo comunque fare un deploy (cioè un’operazione di tipo sistemistico che, in certe aziende è, a ragione, burocratizzata), qui devo far partire un client dello stesso tipo di tutti gli altri, che accede al DB con lo stesso server e journalizza quanto avviene proprio come tutti gli altri. Con tutte le informazioni sulle applicazioni registrate su una tabella di DB, si fanno delle belle report, naturalmente con client sempre di questo tipo.
Ma esiste ancora la grafica Swing?
Purtroppo, il super potere delle web applications ha fatto sì che Swing fosse dimenticata. Mi diceva tempo fa un giovane consulente: “se mi metto a lavorare ad applicazioni con interfaccia Swing, sono fuori mercato; non interessano a nessuno”. Dal suo punto di vista aveva ragione.
Ma ribaltiamo il discorso: i controlli Swing non sono un framework, una metodologia, o chissà che cosa strana: è Java Standard Edition, sono 17 packages di tipo javax.swing. Un client con Swing, che accede al DB con il package java.io, anch’esso Standard Edition, nelle modalità descritte in questo articolo può essere sviluppato da un programmatore junior. Non equivochiamo, non è una questione sindacale-burocratica; è che il tempo che occorre per studiarlo, provarlo e prendere confidenza è veramente basso. Naturalmente occorre avere a disposizione un ambiente di sviluppo grafico di tipo What You See Is What You Get; è assurdo mettersi a combattere con le classi JPanel, JDialog, JWindow e così via. Tutta la grafica può essere creata dall’IDE e sigillata in una abstract class, che rimanda a una classe figlia l’implementazione dei metodi corrispondenti agli eventi. In tal modo, rimane da scrivere codice solo per gli eventi.
Una grande risorsa: le progress-bars
Da un indagine demoscopica risulta che, quando un operatore vede chiaramente che la sua lavorazione sta progredendo, fosse pure in maniera lentissima, è assai più appagato di quando vede la ormai classica “ruotina” che gira, gira… e sembra tanto uno strumento per ipnotizzatori.
Le progress bar si fanno anche in una web application, ma i sistemisti non le gradiscono: ogni refresh è un lavoro in più per ciascuno dei 2, 3 o 4 tiers in cui è strutturato il sistema. L’avvento di AJAX ha migliorato le cose, ma innestarlo per una progress bar non è semplicissimo. Invece la classe javax.swing.JProgressBar è tanto semplice!
Obiezione: ma non puzza tanto di Visual Basic, cosa di cui ogni buon javista ha orrore? È vero, la somiglianza c’è. E purtroppo, anche in informatica le guerre di religione sono dietro l’angolo. Ecco cosa consiglio a chi si facesse questo scrupolo: fate girare questi client in ambiente MacOS e guardate come è carino il look-and-feel! E inoltre, se davvero fosse infestato dai fantasmi del Visual Basic, come mai potrebbe funzionare su un Mac?
La comunicazione client-server
La connessione avviene con le classi ObjectInputStream, BufferedInputStream, ObjectOutputStream, BufferedOutputStream, tutte nel package java.io, a livello Standard Edition. Gli anziani di Java sanno che queste classi erano già presenti in Java 1! Facciamo archeologia informatica? No, semplicemente non abbiamo preconcetti. Con queste classi, la matrice di dati letta è semplicemente serializzata e spedita in HTTP all’indirizzo della servlet con un dispendio di risorse minimo. Il firewall non ha nulla da eccepire, gli sembra una banale conversazione di un internet browser con il web server. Il proxy nemmeno. È chiaro che se io ho una grossa tabella e chiedo semplicemente select * from nome-tabella, metto KO prima il DB server e poi la rete. Ma questo fa parte del senso di responsabilità che ogni progettista o programmatore deve avere.
Perche’ conviene
Di seguito riportiamo una serie di ragioni per cui questo tipo di soluzione ha un senso e merita di essere usata.
Scrivere la servlet sarà complesso, ma una volta sviluppata e collaudata diventerà universale: potrà essere usata per accedere a qualunque DB e potrà essere clonata su diversi application server. Le sue limitazioni sono quelle dell’application server stesso, della quantità di Data Source che sono definiti, e le sue prestazioni obbediscono agli stessi criteri di una qualsiasi web application che acceda ad un DB.
La manutenzione della servlet sarà veramente minima, semmai non si resisterà alla tentazione di darle più funzionalità. I client Swing, invece, come ho già detto possono essere affidati a programmatori junior. Una volta sviluppato, testato e deployato il server, i vari client si fanno in un attimo: superati i primi problemi sulle caratteristiche dei container, l’argomento più ostico di swing, il tempo medio per sviluppare un client con un unico JPanel contenente 10 controlli tra list-box, text-box, bottoni, progress-bar e quant’altro può essere di pochi giorni. Al programmatore, di difficile, sarà richiesto solo di conoscere l’SQL; leggere il risultato di una select consisterà nel testare un codice di ritorno e scorrere un array di righe.
I client non sono installati, sono semplicemente copiati; anzi, possono rimanere su una chiavetta. Anche questa cosa non piace ai sistemisti (scusate, un termine confidenziale, dovrei dire: “responsabili della security digitale”). A loro non piace che, una volta installata la JVM, quell’utente può fare di tutto senza una loro precisa autorizzazione. In realtà, l’autorizzazione c’è ed è rigorosa, è tutta cablata su DB, ma è spostata dall’area sistemistica all’area del coordinamento della produzione, mediante il meccanismo descritto poco più su.
Se il mio client è veramente grosso, posso decidere io quanta RAM dargli: in Windows, per esempio, posso lanciare il cliente con un file .lnk, che conterrà
C:WINDOWSsystem32java.exe -Xms400m -Xmx1024m -jar client.jar
Sarà un tecnico che scriverà per l’operatore questo .lnk, ma l’operatore si sentirà gratificato dal fatto di poter amministrare così bene la RAM del suo PC desktop.
Con questi client si fa anche tutta la reportistica. Con un solo button gli chiedi di scrivere la report in formato XHTML, salvare il file in locale e visualizzarlo con il browser; poi con CTRL+MAIUSC+F12 oppure CTRL+P lo stampi.
Se l’elaborazione dura varie ore, ma l’operatore vede che la sue progress-bar si muovono (meglio se sono più progress-bar gerarchizzate: una generale, un’altra che va avanti e indietro n volte durante l’intero corso di quella che le è sopra, e così via), non si sogna di telefonare all’assistenza per sapere se i server sono OK; va a farsi una passeggiata, ogni tanto torna a sbirciare. Per quanto possa essere lenta l’elaborazione, l’utente avrà una chiara percezione del processo tramite le barre di progressione.
Torniamo alle lavorazioni di back-end
Mentre con una web application posso scrivere in locale solo cookies (se non sono inibiti) e posso fare solo download, con un client posso far tutto. Da una parte è un vantaggio, dall’altra si pone un problema di sicurezza. Se qualcuno riesce a violare il DB e pubblica una nuova versione di un JAR, contenente un virus, è un disastro. Ma questo è un problema di carattere generale. Un altro problema è che, se distribuisci un client java, dai comunque a qualcuno la possibilità di decodificarlo, studiare il codice ed escogitare qualcosa per compiere un atto di sabotaggio, spionaggio o altre porcherie.
La soluzione di compromesso è: usare questo sistema solo per lavorazioni fatte nell’intranet, sotto la protezioni canoniche della rete.
Un altro punto è il costo dell’assistenza tecnica verso l’operatore. Con una web application, al massimo devi intervenire sulle password dimenticate. Ma se l’operatore lavora su un client, può avere problemi di installazione. Con un client Java, però, non c’è installazione, se non quella della JVM. C’è invece, la possibilità di perdita dei file JAR e delle properties; e non gliele puoi mettere anche in un JNLP, altrimenti qualcuno si confonde. D’accordo, l’assistenza tecnica non è zero; per questo è più adatto a una lavorazione interna, come un back-end, perche’ il tecnico è fisicamente, o almeno psicologicamente vicino.
Alternativa ai web service?
Finalmente, l’obiezione iniziale: perche’ non usar un web service? Risposta: questo sistema non è alternativo alla metodologia dei web service. Puoi fare un web service che ti dà accesso a un DB server che sta anche al piano di sotto. Il criterio è: ti interessa fare solo accessi mirati, con modalità rigorosamente prestabilite? Ti cambia poco se devi scrivere 2 oppure 20 WSDL? Allora i WS fanno al caso tuo.
Viceversa: devi mettere su una squadra di operatori di back-end, ma con strutture di dati che cambiano una volta al mese, perche’ il mercato corre? Allora ti tocca organizzare un’altra squadra, anche se molto più piccola, che ti fa quotidianamente manutenzione evolutiva del software. Ecco che la struttura client-server appare come la soluzione ottimale.
Conclusione
Qualcuno potrebbe pensare che il campo di applicazione come questa è troppo limitato: vuol dire che non ha mai fatto il dirigente d’azienda. Le lavorazioni back-end dietro un portale, ad esempio di e-commerce, sono spesso imponenti, sono strategiche e costano lo stipendio di uno stuolo di impiegate e impiegati.
D’accordo, il general manager dirà: “Abbiamo scelto il nostro ERP, poi abbiamo scelto un CRM integrato. Facciamo tutto con quello”. Benissimo. Ma il sottoscritto ha pensato questo articolo per il giovane imprenditore che ha tirato su la sua brava piccola società Srl contandosi i centesimi, conquista quote di mercato ammazzandosi di lavoro e si accontenta di qualcosa che funzioni bene e calzi a pennello, anche se non è un prodotto di marca.
Nato a Roma nel 1953, si occupa di informatica da quando era all‘Università La Sapienza di Roma, dove si è laureato in Fisica nel 1978. Da più di vent‘anni lavora in una azienda grafica di proprietà pubblica, dove ha combattuto la dura battaglia per la modernizzazione della Pubblica Amministrazione italiana. Da una dozzina di anni si occupa di Java. Ha veramente visto molta acqua passare sotto il suo ponte: innumerevoli metodologie, linguaggi, sistemi operativi, tools, millennium bug, sintesi culturali, espressioni del libero pensiero; e ciò gli ha dato una visione disincantata del mondo ICT. Disincantata, non scettica: l‘informatica è una grande risorsa, occorre usarla tutta, e anche onestamente, perché l‘uomo del XXI secolo, cioè in ultima analisi il cliente, riconosce molto presto chi vende fumo e chi invece lo sta aiutando.