giovedì 2 agosto 2007

JSF, serializzazione e classi interne anonime

Anche oggi (che sono in ferie) ho imparato qualcosa di nuovo.

Stavo leggendo il newsgroup it.comp.java e tra i vari thread ne becco uno in cui si tratta di JSF dove un tizio stava cercando di costruirsi un componente custom aggiungendo nel costruttore un valueChangeListener usando una classe interna anonima.
Esempio:

public class MyComponent extends UIInput{
public MyComponent(){
addValueChangeListener(new ValueChangeListener() {
public void processValueChange(ValueChangeEvent event) {
//stuff
}

});

}


}

Una cosa del genere gli dava dei problemi perchè JSF non riusciva a fare un restore dello stato del componente. In passato avevo provato anch'io a usare soluzioni di questo tipo per attaccare a un componente un listener e quelle volte avevo anch'io questo tipo di problemi (che imputavo direttamente a JSF) e risolvevo il dilemma usando una classe esterna.
In realtà la colpa (se così si può dire) è di java !

Quando un componente salva e ripristina lo stato di un componente (listener compresi) si aspetta che le varie informazioni siano serializzabili; in realtà le classi interne anonime non lo sono e non possono esserlo in alcun modo.

A suo tempo era stata anche aperta una segnalazione sul bugcenter della sun che è stato chiuso come "non baco".

L'impossibilità di serializzare/deserializzare queste classi sono da imputare a vari fattori, ad esempio alla mancanza di un costruttore no-arg; nelle classi interne anonime il compilatore aggiunge sì un costruttore ma che accetta come parametro l'enclosing class. Anche il nome di queste classi è dipendente dalla piattaforma e anche dall'implementazione specifica della jvm.
E' un peccato che non sia nemmeno stato accolto come baco, bisognerà conviverci purtroppo ...

Per chi lo desidera sul link ci sono maggiori informazioni.

2 commenti:

Joril ha detto...

Beh, a seconda delle esigenze si puo' evitare la classe anonima facendo si' che sia il componente stesso ad implementare il listener.. Tanto in questi casi e' solo un workaround all'impossibilita' di Java di passare funzioni come parametri.. ;)

Emanuele Gesuato ha detto...

Sì certo, si può sempre evitare l'uso della classe anonima, quando sono caduto nell'errore di usare una classe anonima stavo solo facendo delle prove veloci per vedere se l'action veniva correttamente scatenata. Insomma, prove veloci che purtroppo davano esito negativo ...