mercoledì 9 marzo 2011

JSF e IllegalMonitorStateException in forwarding

Ci sono casi nei quali il puro uso di JSF non è sufficiente: ad esempio quando si vuole inviare un file o uno stream in download attraverso il browser si deve interagire con la richiesta/risposta della classica HttpServlet. In questo caso potrebbe capitare di ottenere il corretto funzionamento del front-end (ossia del browser) ma di trovare una eccezione IllegalMonitorStateException riferita un doForward(..) sul servlet engine. In sostanza quello che avviene è che la servlet invia un risultato ma poi il sistema JSF (e la relativa servlet), non essendo a conoscenza di questa risposta "on-demand" tenta di inviarne una propria. Il servlet engine si accorge di aver già  mandato una intestazione e dei dati (quelli forniti manualmente) e quindi si scatena l'eccezione di cui sopra. La soluzione è abbastanza semplice: si deve invocare il metodo responseComplete() sul FacesContext corrente una volta che si sia finito di inviare la risposta manualmente.

Linux si avvicina a DTrace (?)

Il kernel di Linux include ora una funzionalita' per molti versi paragonabile a DTrace di (Open)Solaris (e derivati): la tracing API. L'idea della tracing API e' quella di inserire dei marcaposto nel codice del kernel per agganciare puntatori a funzione che verranno invocati al raggiungimento delle probes (sonde) nel kernel stesso. Sostanzialmente si tratta di un meccanismo ad eventi per il kernel. L'API viene divisa sostanzialmente in due parti:
  • trace points: ovvero dichiarazione delle sonde. Mediante una serie di macro si possono definire funzioni generiche (con relativi parametri) e invocare tali funzioni in punti dle codice del kernel. Le funzioni non faranno altro che andare a richiamare i listener agganciati alle sonde.
  • trace events: sono un API di livello piu' alto costruita sui tracepoints. Sostanzialmente un evento e' un trace point con in piu' dei dati (contenuti in una struttura) che puo' essere esaminata lato utente. L'idea e' che quando scatta l'evento la struttura dati venga copiata con dei dati forniti da del codice (es. un modulo caricato).

In userspace occorre abilitare il tracing editando i file del sysfs sotto alla directory kernel/debug/tracing inserendo il classico 1 negli eventi (o nei sottosistemi) per abilitare il tracing. A questo punto si avra' una printk() gratuita per l'evento abilitato, o se si e' scritto un proprio evento si avra' l'esecuzione del codice di tracing specificato.
Si e' ancora abbastanza lontani dalla potenza di DTrace, anche se strumenti quali perf promettono molto bene, ad ogni modo penso che questa sia una bella mossa da parte del kernel Linux che potrebbe portarlo ancora piu' pesantemente a sostituire quei sistemi enterprise che stanno difendendo con i denti la loro posizione. Per maggiori informazioni si veda questo ottimo articolo.