Newsgroup: it.comp.java
Titolo: eseguire una trap in maniera elegante

Salve a tutti,
se avete, nei vostri programmi, dei controlli che devono assolutamente
tornare una risposta positiva
come ad esempio assicurarsi che un determinato file esista, sia
leggibile oppure
non sia vuoto, etc etc...
e desiderate che in caso negativo l'intera applicazione si interrompa
come implementate, in maniera elegante, questa funzionalità ?
Esempio: (occhio alla negazione "!")
if ( !MiaClasseUtilità.controllaCheQuestoFileSiaPresente("file.txt") )
    ...esegui la trap()
Cioè se tale file "file.txt" NON esiste
potrei proseguire con un metodo che mostra un opportuno messaggio
d'errore e poi invoca la System.exit(1);
Mi chiedevo se esiste una maniera più corretta, più elegante, per fare
ciò.
Grazie.

il 06/02/2009 0.30, Scrive Giordano 43447104:

Forse non ho capito, un semplice try/catch non va bene? Ad esempio:
try {
   File f = MiaClasseUtilita.getFileControllato("file.txt");
   prosegui(f);
} catch (Throwable t) {
   trap(t);
}
public class MiaClasseUtilita {
   public static File getFileControllato(String nome) {
      File f = null;
      if (controllaCheQuestoFileSiaPresente(nome)
        f = new File(nome).getAbsoluteFile();
      if (f != null) return f;
      throw new NullPointerException("Panico! File("+nome+")="+f);
   }
   public static boolean controllaCheQuestoFileSiaPresente(String nome) {
     RunTimeException e = null;
     StringBuffer sb = new StringBuffer(nome);
     try {
       File f = new File(nome).getAbsoluteFile();
       if (!f.exists()) sb.append(" non esiste");
       if (!f.isFile()) sb.append(" non é un file");
       if (!f.canRead() sb.append(" non è leggibile");
       if (!f.length() > 0) sb.append(" è vuoto");
       if (!sb.toString().equals(nome))	
         e = new RuntimeException(sb.toString());
     } catch (Throwable t) {
       sb.append(" "+t.toString());
       e = new RuntimeException(sb.toString(), t);
       e.fillInStackTrace();
     }
     if (e == null) return true;
     trow e;
   }
}
-- 
Dr.Ugo Gagliardelli,Modena,ItalyCertifiedUindoscrasherAñejoAlcoolInside
Spaccamaroni andate a cagare/Spammers not welcome/Spammers vão à merda
Spamers iros a la mierda/Spamers allez vous faire foutre/Spammers loop
schijten/Spammers macht Euch vom Acker/Spamerzy wypierdalac'

trap(t)
è il metdo che al suo interno conterrà l'istruzione  System.exit
(1);  ?

 
A piacimento, anche se non e' strettamente necessario, dipende da come 
e' fatta l'applicazione, ad esempio questo non necessita di System.exit 
ma se proprio vuoi...:
public class Faqualcosa {
   File ilFile;
   public static int main(String[] args) {
    try {
      File f = MiaClasseUtilita.getFileControllato(args[0]);
      Faqualcosa fq = new Faqualcosa().prosegui(f);
    } catch (Throwable t) {
      Faqualcosa.trap(t);
    }
   }
   Faqualcosa() {
     super();
   }
   public Faqualcosa(String ilNome) {
     this();
     prosegui(MiaClasseUtilita.getFileControllato(ilNome));
   }
   static void trap(Throwable t) {
      System.out.println("Il file indicato fa cagare!\n"
         + t.getMessage()
         + "\n"
         + t.getCause());
/* se mi va:
      System.exit(1);
*/
   }
   private void prosegui(File f) {
     ilFiile = f;
// prosegue perche' f non e' null in quanto sono un metodo privato e 	 
  // se sono qui e' stato il main o il costruttore String che manda a
// spendere se il file non e' buono
   }
}
Ovviamente il costruttore Faqualcosa(String) potresti anche non averlo.


Mille grazie,
adottero questo stile,
mi chiedo solo se un "numeroso" uso delle try/catch introduca alla
fine un aumento delle risorse impiegate ?
Le try/catch spendono molte più risorse di sistema di un normale
controllo if, è così ?

il 06/02/2009 12.15, Scrive Giordano 43447104:

Non so se siano effettivamente molte, sicuramente di piu', ma farne a 
meno e' praticamente impossibile.


 controllo if, č cosě ?
Sě, č cosě (cosa facilmente verificabile con poche righe di codice di test).
Se hai tante iterazioni che passano per quel controllo mi sembra 
decisamente preferibile usare il tuo metodo originario (l'if) piuttosto 
di una try/catch.

E se, a seguito dell' if, creiamo un oggetto Errore che associamo ad
una classe ErroreListener (la quale quest'ultima -per esempio- ha il
compito di visualizzare il messaggio di errore su una GUI)
Come giudicate una implementazione del genere ?


Usa le exception a meno che tu non stia scrivendo un videogame
considera anche che nell'esempio che hai fatto tu l'accesso al file e l'IO
in generale e' diversi ordini di grandezza piu' lento della cpu e quindi
delle exception, quindi il tempo speso in exception e' nullo
ciao
N
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

Ho deciso... userò le Exceptions... le odio -forse perchè si devono
scrivere, e ripetere, sempre le stesse linee di codice.
In passato generavo al volo una classe che mostrava un opportuno
messaggio d'errore e poi invoca la System.exit(1),
ma se voi mi consigliate che è utile fare uso dei try-catch io "mi
metto in riga" con piacere :)

 scrivere, e ripetere, sempre le stesse linee di codice.
Sei fuori strada. 
L'idea è quella di lanciare un'eccezione che estende RuntimeException e 
ti gestirla in un punto centralizzato. Tutte le eccezioni *di quel tipo* 
andranno gestite in quel punto, perchè si tratta appunto di situazioni
non recuperabili dove l'unica cosa che puoi fare è mostrare un messaggio 
di errore e terminare il programma.
Mi raccomando però, questo non significa che *tutte* le eccezioni debbano
per forza venir gestite in questa maniera.
Se fosse una web application saprei dirti dove e come è possibile effettuare
questa gestione centralizzata, ma siccome mi par di capire si tratti di qualche
applicativo desktop, non ho idea.

 di una try/catch.
Beh, consideriamo che stiamo parlando di Exception, che dovrebbero 
appunto presentarsi eccezionalmente.
D'altra parte praticamente tutte le librerie che conosco utilizzano il 
throw per segnalare le anomalie, se non ci metti dei try/catch come fai 
valutare cos'e' successo con un if?
Poi, soprattutto in un ambiente vocato al multi-threading come il Java, 
come fai a definire un punto di controllo unico?
Per non parlare del debug, consultando la stack-trace riesci sempre a 
capire dov'e' l'inghippo, e perche' si e' verificato, nel tuo ipotetico 
punto di controllo come faresti a ricostruire la genesi dell'anomalia?
In generale penso che un messaggio di errore, oltre che indicare il tipo 
di errore, dovrebbe anche illustrane le ragioni, altrimenti ricadiamo 
nel pattern adottato dalla Microsoft, che sinceramente mi sembra il 
peggiore in assoluto.


 scrivere, e ripetere, sempre le stesse linee di codice.
In effetti questa è una cosa che considero sempre parecchio pallosa
try {
} catch(ExceptionTipo1 e) {
  gestione e
...
} catch(ExceptionTipoN e) {
  gestione e
}
Se "gestione e" è identico devi scrivere tonnellate di righe uguali. Io
ho risolto usando un metodo "logAndEx" che logga l'eccezione, fa quel
che deve fare ed eventualmente ne manda una di un tipo mio che serve per
il resto del programma. Rimane comunque la pallosità di dover scrivere
una barcata di 'catch', sarebbe bella una sintassi mono riga (mi pare in
python ci sia qualcosa del genere)
-- 
bye
DKano

Posso vedere il codice di questo tuo metodo "logAndEx" ?

 Se "gestione e" è identico devi scrivere tonnellate di righe uguali. 
E come mai ti trovi a gestire valanghe di eccezioni sparpagliate per il codice?
Quali sono questi casi pratici dove è necessaria una cosa del genere?

cicap ha scritto:

E chi ha detto che sono sparpagliate per il codice?
Ci sono svariati metodi (per es. newInstance() di Constructor) che
"throws-ano" più eccezioni. Se a me non interessa distinguere fra le
diverse eccezioni, devo comunque inserire n blocchi "catch"
-- 
bye
DKano

 
Niente di che, le stese cose che faresti dentro il cacth. Cosě al volo:
logAndEx(String msg, Exception e){
	log().error(mgs, e);
	qualche altra elaborazione specifica comune a tutti i catch
	ed, eventualmente
	throw MyException(msg,e);
}
MyExecption indica "elaborazione fallita" ed č quella che viene poi
propagata in su. In questo modo a livello piů alto tratto solo con la
mia, tranne nei casi in qui effettivamente mi serve sapere che tipo di
eccezione ha dato il problema per gestire le cose differentemente.
-- 
bye
DKano



Non si parlava di eccezioni della jdk, ma di eccezioni applicative.
E comunque basta un blocco con catch su Exception invece di 'n' catch.

 E comunque basta un blocco con catch su Exception invece di 'n' catch.
Si ma non mi piace troppo, mi da l'idea di perdere il controllo... mi
spiego: metti caso che qualcosa venga modificato nel blocco try e che
questo codice modificato implichi la gestione di una (n+1)-esima
eccezione? Mettendo Exception nel catch rischi di non accorgertene,
mentre invece enumerandole il compilatore (o eclipse o chi per lui) dà
errore.
Insomma mi piacerebbe una sintassi tipo
catch(ExTipo1, ExTipo2 ... e)
-- 
bye
DKano

Io, appena mi libero da questo lavoro (multi-threads in C), ri-metto
mano al mio progetto
Lo continuo secondo il modello del 1° codice proposto in questo thread
(quindi try-catch) adattandolo in modo da inviare il messaggio
d'errore alla GUI.
Qualcuno potrebbe scrivere 2 righe funzionanti tanto da farmi da linea-
guida ?
Grazie

 Usa le exception a meno che tu non stia scrivendo un videogame
Comunque il videogame non lo farei in Java, magari il GC passa mentre
stai per fraggare qualcuno :)

 stai per fraggare qualcuno :)
lol
si congela anche lui perņ :)
Si potrebbe inserire come effetto... il "malefico garbagiatore congelante"
-- 
bye
DKano

 Grazie
Nicola


 libro di Conan :-))))))))
Conan... Doyle(?)
...del tipo "Uno Studio In Rosso" ??
:-))

Giordano ha scritto:

Magari "il mastino dei Javasterville" :)
-- 
bye
DKano

 eccezione ha dato il problema per gestire le cose differentemente.
E quale sarebbe la differenza con il metodo trap(Throwable)?
Incapsulare qualsiasi eccezione in una tua eccezione al solo scopo di 
indicare "elaborazione fallita", mi sembra una motivazione debole. In 
genere progetti delle eccezioni applicative per indicare delle eccezioni 
tipiche dell'applicazione, ad esempio;
DatiInconsistentiException(String dato) extends RunTimeException {
    protected static MessageFormat NOT_CODPAG =
      new MessageFormat("Il codice pagamento\"{1}\" non e' ammesso");
    DatiInconsistentiException(String dato) {
      super(dato);
    }
}
CodicePagamentoException extends DatiInconsistentiException {
    CodicePagamentoException(String dato) {
      super(NOT_CODPAG.format(dato));
    }
}
Ma per indicare che un file non e' leggibile le ecezioni delle classi 
java.io
 mi sembra che vadano piu' che bene, anzi sono auspicabili 
proprio per risalire alla genesi dell'eventuale problema.


 indicare "elaborazione fallita", mi sembra una motivazione debole. In
Non č il solo scopo, diciamo che mi fa comodo da un certo livello in su
gestire una mono eccezione perché qualunque cosa sia successa 'a basso
livello' comunque devo comportarmi nello stesso modo. Per livello
intendo in senso OS-istico; tanto per fare un es. livello basso: classi
che gestiscono la comunicazione con un jms, livello piů alto: classi che
si occupano del contenuto dei messaggi. Se per qualche motivo al primo
livello qualcosa va storto o la gestisco lě (se rimediabile) quindi
differenziando il comportamento a seconda delle eccezioni oppure invio
una mia eccezione per indicare una condizione non rimediabile ma gestita
(l'ho 'vista', l'ho elaborata, non ci cavo i piedi).
-- 
bye
DKano