venerdì 24 settembre 2010
Flex è morto... anzi, no, aspetta!
È ufficiale, come spiegato in questa pagina, Adobe non svilupperà più Flex/Flash Builder per Linux, neanche uno straccio di versione alpha.
Chi è riuscito a scaricare l'ultima versione avrà tempo di usarla fino alla sua morte programmata, il 31 Dicembre. Con l'anno nuovo o ci si converte a un altro sistema, o si va di SDK.
Forse era prevedibile, d'altronde Adobe vuole monetizzare attraverso i tool legati a Flex - pur mantenendo l'SDK gratuito - e non sembra esserci spazio nel ristretto mercato di sviluppatori Linux.
Per chi non vuole rinunciare a Eclipse segnalo il plugin Axdt, che agevola un po' la scrittura e l'esecuzione del codice. Purtroppo lo sviluppo è ancora agli inizi, e ad esempio non c'è l'evidenziazione della sintassi per i file MXML, e l'editor ActionScript non considera gli import di Flex, ad esempio spark.components.Label.
(continua)
venerdì 10 settembre 2010
Come la pensa Joel
Joel e il Software, Mondadori Informatica, 2005 - 384 pagine
"La vita è troppo corta per permetterti di odiare il tuo lavoro"
Joel e il Software, p. xiv
Comincia oggi la serie delle mie grandi recensioni!
Joel e il Software è una raccolta di alcuni articoli sulla programmazione, sull'organizzazione aziendale e sul software in generale apparsi sul blog di Joel Spolsky fino al 2004.
Qualcuno potrebbe chiedersi: "Perché mai dovrei leggere un libro del 2004?"
Perché alcuni argomenti sono ancora attuali.
"Perché hai comprato un libro del 2004?"
Perché alcuni argomenti sono ancora attuali.
"Perché hai comprato un libro del 2004?"
Perché l'ho trovato in offerta, a un terzo del prezzo.
"Perché dovrei comprare un libro per leggere più o meno le stesse cose che
si possono trovare sul sito dell'autore?"
Non so, per leggerle più comodamente?
"Perché dovrei comprare un libro per leggere più o meno le stesse cose che
si possono trovare sul sito dell'autore?"
Non so, per leggerle più comodamente?
Spolsky scrive con uno stile molto scorrevole (a differenza di me :-), che non stanca mai, e mentre ti intrattiene ti insegna anche qualcosa.
Si capisce che è una persona molto pragmatica, che bada al sodo e al risultato.
Alcuni capitoli sono delle perle, come il 25 sul "segreto dell'iceberg", altri meno, come il 20, una specie di "guida al reclutamento del programmatore perfetto", che non mi trova molto d'accordo (ebbene sì, caro Joel, "logorroico" è ben diverso da "brillante"!).
Si capisce che è una persona molto pragmatica, che bada al sodo e al risultato.
Alcuni capitoli sono delle perle, come il 25 sul "segreto dell'iceberg", altri meno, come il 20, una specie di "guida al reclutamento del programmatore perfetto", che non mi trova molto d'accordo (ebbene sì, caro Joel, "logorroico" è ben diverso da "brillante"!).
Purtroppo la traduzione italiana è un po' approssimativa, tra errori di battitura e veri e propri errori di traduzione.
Due esempi veloci.
A pagina 200 parla di "numero primo", quando l'articolo originale parla semplicemente di "integer".
Poi, a pagina 324, "the SQL Server classes" diventano "le classi Server di SQL"!
Due esempi veloci.
A pagina 200 parla di "numero primo", quando l'articolo originale parla semplicemente di "integer".
Poi, a pagina 324, "the SQL Server classes" diventano "le classi Server di SQL"!
Concludendo, JoS è un libro che consiglio comunque a chi lavora in
questo ambito, programmatore o manager, possibilmente in versione originale, ma è leggibile anche in italiano.
Buona lettura!
questo ambito, programmatore o manager, possibilmente in versione originale, ma è leggibile anche in italiano.
Buona lettura!
mercoledì 16 giugno 2010
Non fate come Urgo!
Primo post di bricolage!
Dovevo riempire uno spazio vuoto tra il termosifone e il muro, quindi ho pensato di metterci uno scaffale. Non trovandone di misura adeguata ho pensato: "Me lo faccio da me!".
Ecco cosa serve:
Io ho usato un pannello 40x100, quindi per prima cosa l'ho tagliato per la lunghezza in modo da ottenere due pezzi del genere:
Dopo aver tagliato i due pezzi suddetti in tre "sottopezzi" ho preso quelli da 71 centimetri (i lati dello scaffale) e ho praticato 6 + 6 fori, così:
Passiamo ora ai ripiani.
Ho forato i bordi dei due ripiani "interi" (4 fori per pezzo):
E infine i bordi dei due ripiani piccoli, che vengono appesi da un lato solo (2 fori per pezzo):
Non resta che levigare tutti i pezzi con carta abrasiva (può andare a grana 120)
e assemblare il tutto con le viti.
Ed ecco a voi il risultato finale!
Alla prossima impresa!
Disclaimer: Non fate come Urgo!
Dovevo riempire uno spazio vuoto tra il termosifone e il muro, quindi ho pensato di metterci uno scaffale. Non trovandone di misura adeguata ho pensato: "Me lo faccio da me!".
Non fate come Urgo!
Usate il legno per qualcosa di utile!
Ecco cosa serve:
- una tavola di abete 40x100 (o meglio 20x200, anche se è più scomoda da trasportare vi risparmiate un po' di taglio)
- un trapano/avvitatore
- un seghetto alternativo (o altro tipo di sega)
- 12 viti da legno di lunghezza adeguata
- carta abrasiva
Non fate come Urgo!
Usate gli occhialini di protezione!
Io ho usato un pannello 40x100, quindi per prima cosa l'ho tagliato per la lunghezza in modo da ottenere due pezzi del genere:
Dopo aver tagliato i due pezzi suddetti in tre "sottopezzi" ho preso quelli da 71 centimetri (i lati dello scaffale) e ho praticato 6 + 6 fori, così:
Passiamo ora ai ripiani.
Ho forato i bordi dei due ripiani "interi" (4 fori per pezzo):
E infine i bordi dei due ripiani piccoli, che vengono appesi da un lato solo (2 fori per pezzo):
Non resta che levigare tutti i pezzi con carta abrasiva (può andare a grana 120)
e assemblare il tutto con le viti.
Ed ecco a voi il risultato finale!
Alla prossima impresa!
Disclaimer: Non fate come Urgo!
lunedì 7 giugno 2010
Comunicazione tra Flex, JavaScript e Applet Java
A volte può essere conveniente far comunicare un'applicazone Flex con del codice JavaScript, o con un'applet Java, magari per sfruttare il multithreading.
Sembra una cosa complicata, ma non è così.
Supponiamo di voler chiamare il metodo
Basta una riga di codice ActionScript:
Perché il metodo sia visibile deve essere dichiarato pubblico:
Se la computazione è pesante ricordatevi di avviarla in un thread separato, altrimenti l'esecuzione si bloccherà finché il metodo non ritorna.
Naturalmente l'applet deve essere inclusa nello stesso wrapper HTML:
Passiamo ora alla comunicazione da un'applet java a un'applicazione Flex.
In questo caso le cose si complicano un po'.
Prima di tutto è necessario includere il parametro
Poi bisogna registrare il metodo ActionScript in modo che sia accessibile tramite JavaScript:
Ora si costruisce una funzione JavaScript che chiama il metodo registrato come
Da quanto ho sperimentato questa funzione deve essere dichiarata dopo il tag APPLET affinché sia visibile al codice java.
È ora possibile chiamare
Come si vede gli eventuali argomenti alla funzione JavaScript vanno passati in un array.
Inoltre per usare
Ulteriori informazioni sulla comunicazione tra Flex e JavaScript si possono trovare al seguente link:
http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7f17.html
Per la comunicazione Java - JavaScript si veda:
https://jdk6.dev.java.net/plugin2/liveconnect/
Mentre per una panoramica sui metodi di
http://java.sun.com/javase/6/webnotes/6u10/plugin2/liveconnect/jsobject-javadoc/netscape/javascript/JSObject.html
È tutto, buona programmazione!
Sembra una cosa complicata, ma non è così.
Supponiamo di voler chiamare il metodo
work
della nostra applet, e di passargli una stringa come argomento.Basta una riga di codice ActionScript:
ExternalInterface.call("document.workerApplet.work", arg);
Perché il metodo sia visibile deve essere dichiarato pubblico:
public void work(String arg) {
/* ... */
}
/* ... */
}
Se la computazione è pesante ricordatevi di avviarla in un thread separato, altrimenti l'esecuzione si bloccherà finché il metodo non ritorna.
Naturalmente l'applet deve essere inclusa nello stesso wrapper HTML:
<APPLET id="workerApplet"
code="WorkerApplet.class" codebase="." align="baseline"
width="0" height="0" MAYSCRIPT="true" />
code="WorkerApplet.class" codebase="." align="baseline"
width="0" height="0" MAYSCRIPT="true" />
Passiamo ora alla comunicazione da un'applet java a un'applicazione Flex.
In questo caso le cose si complicano un po'.
Prima di tutto è necessario includere il parametro
MAYSCRIPT
nel tag APPLET
.Poi bisogna registrare il metodo ActionScript in modo che sia accessibile tramite JavaScript:
// registration
private function registerCallback():void {
ExternalInterface.addCallback(
"externalComputationComplete",
externalComputationComplete);
}
// callback
public function externalComputationComplete(s:String):void {
Alert.show("Applet returned: " + s);
}
private function registerCallback():void {
ExternalInterface.addCallback(
"externalComputationComplete",
externalComputationComplete);
}
// callback
public function externalComputationComplete(s:String):void {
Alert.show("Applet returned: " + s);
}
Ora si costruisce una funzione JavaScript che chiama il metodo registrato come
"externalComputationComplete"
:<SCRIPT LANGUAGE="JavaScript">
function callFlexApp(s) {
var flexApp = document.getElementById("flexApp");
flexApp.externalComputationComplete(s);
}
</SCRIPT>
function callFlexApp(s) {
var flexApp = document.getElementById("flexApp");
flexApp.externalComputationComplete(s);
}
</SCRIPT>
Da quanto ho sperimentato questa funzione deve essere dichiarata dopo il tag APPLET affinché sia visibile al codice java.
È ora possibile chiamare
callFlexApp
da Java:netscape.javascript.JSObject.getWindow(this)
.call("callFlexApp", new Object[] {"done"});
.call("callFlexApp", new Object[] {"done"});
Come si vede gli eventuali argomenti alla funzione JavaScript vanno passati in un array.
Inoltre per usare
JSObject
bisogna includere nel classpath il JAR $JAVA_HOME/jre/lib/plugin.jar
Ulteriori informazioni sulla comunicazione tra Flex e JavaScript si possono trovare al seguente link:
http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7f17.html
Per la comunicazione Java - JavaScript si veda:
https://jdk6.dev.java.net/plugin2/liveconnect/
Mentre per una panoramica sui metodi di
JSObject
il javadoc si trova all'indirizzo:http://java.sun.com/javase/6/webnotes/6u10/plugin2/liveconnect/jsobject-javadoc/netscape/javascript/JSObject.html
È tutto, buona programmazione!
domenica 16 maggio 2010
Mmmmercurial!
Se sentendo la parola Subversion vi si rimescola lo stomaco, se CVS per voi significa Come Volevasi Sfasciare, se non usate nessun tipo di controllo di versione perché temete di impazzire... Usate Mercurial!
Mercurial è un sistema di controllo di versione distribuito, in cui esistono più copie del repository, almeno una per sviluppatore/autore.
I vantaggi di questo approccio sono molteplici, per i dettagli vi rimando alla documentazione esistente, in particolare all'ottimo tutorial di Joel Spolsky che si trova qui, ma anche la documentazione sul sito ufficiale non è male.
Con
Se volete un'interfaccia grafica più "corposa" potete installare TortoiseHg, che fornisce anche vari tool ed estensioni interessanti.
Ci risentiamo tra qualche anno, con un post che comincerà pressappoco così:
"Se solo a sentire la parola Mercurial vi vengono le convulsioni..."
Mercurial è un sistema di controllo di versione distribuito, in cui esistono più copie del repository, almeno una per sviluppatore/autore.
I vantaggi di questo approccio sono molteplici, per i dettagli vi rimando alla documentazione esistente, in particolare all'ottimo tutorial di Joel Spolsky che si trova qui, ma anche la documentazione sul sito ufficiale non è male.
Con
hg serve
potrete esplorare graficamente i vostri repositori puntando il browser a http://localhost:8000/Se volete un'interfaccia grafica più "corposa" potete installare TortoiseHg, che fornisce anche vari tool ed estensioni interessanti.
Ci risentiamo tra qualche anno, con un post che comincerà pressappoco così:
"Se solo a sentire la parola Mercurial vi vengono le convulsioni..."
sabato 8 maggio 2010
Nouveau... ou vieux?
Ho appena installato Ubuntu 10.04 LTS su uno dei miei sistemi, e devo dire che, dopo i necessari aggiustamenti, si rivela una bella distribuzione.
Ho addirittura più che dimezzato i tempi di caricamento rispetto alla Kubuntu 8.04 che avevo prima!
Uno degli "aggiustamenti" che si sono resi necessari ha riguardato il driver libero Nouveau, che sostituisce a partire da questa versione di Ubuntu il vecchio driver libero "nv", e come quest'ultimo fornisce solo l'accelerazione 2D.
Il sistema in questione è equipaggiato con una GeForce4 MX con memoria condivisa, e già all'avvio del cd si sono presentati disturbi grafici degni di un vecchio televisore CRT (!) che rendevano lo schermo quasi illeggibile. Questi sono continuati anche nel sistema installato.
La soluzione veloce è stata l'installazione del driver proprietario di NVIDIA, attuata con pochi click da un'icona che mi avvertiva della sua disponibilità.
Quindi la morale della favola è: se avete una scheda NVIDIA, e dopo l'installazione di Ubuntu 10.04 vi sembra che il vostro computer debba esplodere da un momento all'altro, installate senza indugi il driver proprietario!
Alla prossima!
Ho addirittura più che dimezzato i tempi di caricamento rispetto alla Kubuntu 8.04 che avevo prima!
Uno degli "aggiustamenti" che si sono resi necessari ha riguardato il driver libero Nouveau, che sostituisce a partire da questa versione di Ubuntu il vecchio driver libero "nv", e come quest'ultimo fornisce solo l'accelerazione 2D.
Il sistema in questione è equipaggiato con una GeForce4 MX con memoria condivisa, e già all'avvio del cd si sono presentati disturbi grafici degni di un vecchio televisore CRT (!) che rendevano lo schermo quasi illeggibile. Questi sono continuati anche nel sistema installato.
La soluzione veloce è stata l'installazione del driver proprietario di NVIDIA, attuata con pochi click da un'icona che mi avvertiva della sua disponibilità.
Quindi la morale della favola è: se avete una scheda NVIDIA, e dopo l'installazione di Ubuntu 10.04 vi sembra che il vostro computer debba esplodere da un momento all'altro, installate senza indugi il driver proprietario!
Alla prossima!
venerdì 30 aprile 2010
Java Base
Ripubblico qui una guida alle basi del linguaggio Java che ho scritto un po' di tempo fa.
Essendo del 2006 prendete quello che c'è scritto qui dentro con beneficio di inventario - anche se è sostanzialmente corretto.
Al link seguente trovate la guida in formato HTML, leggibile e scaricabile, l'archivio con un file HTML per ognuno dei 10 capitoli, e la guida in formato PDB per Plucker.
Una piccola correzione:
Nella sezione Classi annidate, “inner” e “nested” sono considerati sinonimi. In realtà le classi nested sono genericamente definite nel corpo di un'altra classe o interfaccia, mentre le classi inner sono classi nested non statiche. Una spiegazione dettagliata del tutto si può trovare nelle specifiche ufficiali: http://java.sun.com/docs/books/jls/third_edition/html/classes.html - introduzione, secondo paragrafo, e capitolo 8.1.3, primo paragrafo. Grazie a PGI-Bis del forum di Hardware Upgrade per i chiarimenti.
Novità! Ho reso disponibile la guida come singolo file HTML - in fondo alla pagina trovate anche il link per scaricarlo.
Novità2! Se vi interessa JavaCC - ovvero come creare automaticamente parser in java - ho scritto un piccolo tutorial, qui:
Sperando che sia utile a qualcuno, alla prossima!
Essendo del 2006 prendete quello che c'è scritto qui dentro con beneficio di inventario - anche se è sostanzialmente corretto.
Al link seguente trovate la guida in formato HTML, leggibile e scaricabile, l'archivio con un file HTML per ognuno dei 10 capitoli, e la guida in formato PDB per Plucker.
Una piccola correzione:
Nella sezione Classi annidate, “inner” e “nested” sono considerati sinonimi. In realtà le classi nested sono genericamente definite nel corpo di un'altra classe o interfaccia, mentre le classi inner sono classi nested non statiche. Una spiegazione dettagliata del tutto si può trovare nelle specifiche ufficiali: http://java.sun.com/docs/books/jls/third_edition/html/classes.html - introduzione, secondo paragrafo, e capitolo 8.1.3, primo paragrafo. Grazie a PGI-Bis del forum di Hardware Upgrade per i chiarimenti.
Novità! Ho reso disponibile la guida come singolo file HTML - in fondo alla pagina trovate anche il link per scaricarlo.
Novità2! Se vi interessa JavaCC - ovvero come creare automaticamente parser in java - ho scritto un piccolo tutorial, qui:
Sperando che sia utile a qualcuno, alla prossima!
giovedì 29 aprile 2010
Flex file upload
Recentemente ho dovuto implementare l'upload di file a una servlet con Adobe Flex. Poiché ho incontrato alcuni ostacoli ho deciso di postare la soluzione a cui sono arrivato, nell'eventualità che sia utile ad altri nella stessa situazione.
Come primo tentativo ho usato il metodo "canonico", ovvero chiamare il metodo
Nella risposta della servlet era immersa una rassicurante scritta - "file uploaded" - ma il file caricato risultava irreperibile.
Dopo una verifica con firebug ho scoperto che nella richiesta non veniva inviata la JSESSIONID, necessaria al server per identificare la sessione in cui viene fatto l'upload.
Poco male, visto che basta appendere all'URL di richiesta la stringa ";jsessionid=", seguita dalla ID.
Il problema è che bisogna modificare l'interfaccia web per recuperare in qualche modo questa ID.
Come se non bastasse l'applicazione flash si blocca fino a che l'upload non è completato, e questo non è un bene. Tra l'altro, per file di dimensione superiore a qualche kilobyte, viene bloccato tutto il browser, con un consumo esorbitante di memoria RAM.
Questo evidentemente è dovuto a un memory leak nel Flash Player, e accade sia con Firefox che con Chrome che con Opera.
Scartata questa soluzione, quando ormai mi stavo convincendo ad usare una "pezza" AJAX, mi sono rituffato in Google, e mi sono imbattuto in una comoda classetta ActionScript, MultipartURLLoader, che costruisce correttamente la richiesta HTTP per l'upload contemporaneo di più file.
Ho quindi dovuto commentare alcune linee (in particolare la 374 e quelle dalla 408 alla 417) per adattarla al mio caso di file singolo.
Per poter usare questa classe è necessario usare il caricamento di file locali, una caratteristica introdotta con la versione 10 del Flash Player, mediante il metodo
Quando il file è caricato in memoria viene chiamato il gestore
Una volta completato l'upload il gestore
comincerà ad essere chiamato, fino allo scaricamento completo della risposta, che coinciderà con l'invocazione del gestore
E questo è tutto!
Happy Flexing!
Come primo tentativo ho usato il metodo "canonico", ovvero chiamare il metodo
upload
di FileReference.Nella risposta della servlet era immersa una rassicurante scritta - "file uploaded" - ma il file caricato risultava irreperibile.
Dopo una verifica con firebug ho scoperto che nella richiesta non veniva inviata la JSESSIONID, necessaria al server per identificare la sessione in cui viene fatto l'upload.
Poco male, visto che basta appendere all'URL di richiesta la stringa ";jsessionid=", seguita dalla ID.
Il problema è che bisogna modificare l'interfaccia web per recuperare in qualche modo questa ID.
Come se non bastasse l'applicazione flash si blocca fino a che l'upload non è completato, e questo non è un bene. Tra l'altro, per file di dimensione superiore a qualche kilobyte, viene bloccato tutto il browser, con un consumo esorbitante di memoria RAM.
Questo evidentemente è dovuto a un memory leak nel Flash Player, e accade sia con Firefox che con Chrome che con Opera.
Scartata questa soluzione, quando ormai mi stavo convincendo ad usare una "pezza" AJAX, mi sono rituffato in Google, e mi sono imbattuto in una comoda classetta ActionScript, MultipartURLLoader, che costruisce correttamente la richiesta HTTP per l'upload contemporaneo di più file.
Ho quindi dovuto commentare alcune linee (in particolare la 374 e quelle dalla 408 alla 417) per adattarla al mio caso di file singolo.
Per poter usare questa classe è necessario usare il caricamento di file locali, una caratteristica introdotta con la versione 10 del Flash Player, mediante il metodo
load
di FileReference, chiamato nel gestore dell'evento SELECT:/* in constructor or wherever you want */
fileRef.addEventListener( Event.SELECT,
fileSelected );
fileRef.addEventListener( Event.COMPLETE,
loadComplete );
...
/* in fileSelected() */
fileRef.load();
fileRef.addEventListener( Event.SELECT,
fileSelected );
fileRef.addEventListener( Event.COMPLETE,
loadComplete );
...
/* in fileSelected() */
fileRef.load();
Quando il file è caricato in memoria viene chiamato il gestore
loadComplete()
, nel quale possiamo iniziare l'upload:private var multipartLoader:MultipartURLLoader =
new MultipartURLLoader();
...
var loader:URLLoader =
multipartLoader.loader;
loader.addEventListener(Event.COMPLETE,
uploadComplete);
loader.addEventListener(
ProgressEvent.PROGRESS,
progressHandler);
...
multipartLoader.addFile(fileRef.data,
fileRef.name,
"file",
"application/octet-stream");
multipartLoader.load(urlString);
new MultipartURLLoader();
...
var loader:URLLoader =
multipartLoader.loader;
loader.addEventListener(Event.COMPLETE,
uploadComplete);
loader.addEventListener(
ProgressEvent.PROGRESS,
progressHandler);
...
multipartLoader.addFile(fileRef.data,
fileRef.name,
"file",
"application/octet-stream");
multipartLoader.load(urlString);
Una volta completato l'upload il gestore
progressHandler()
comincerà ad essere chiamato, fino allo scaricamento completo della risposta, che coinciderà con l'invocazione del gestore
uploadComplete()
.E questo è tutto!
Happy Flexing!
Iscriviti a:
Post (Atom)