Newsgroup: it.comp.java
Titolo: eccezione non catturata in Thread.run()

Ho una classe che estende Thread e implementa il metodo run().
In questo metodo vorrei non catturare un eccezione ma il compilatore mi 
da errore. Ho letto su un manuale di java che se un'eccezione non è 
catturata, viene rilanciata automaticamente al chiamante. Se uso questo 
codice
---
public class Pippo extends Thread {
   public Pippo() {
   }
   public void run() {
     try {
	// codice che lancia un'eccezione
     }
     finally {
	// eccezione non catturata e rilanciata al chiamante
     }
   }
}
---
il compilatore mi segnala errore nel blocco try perchè non catturo 
l'eccezione. Credo che per non far segnalare errore, dovrei dichiarare 
il metodo run throws Exception, ma il prototipo di Thread.run() non 
consente di lanciare eccezioni. Se è così, allora il libro ha preso una 
cantonata perchè ha mancato di dire che, quando non si cattura 
un'eccezione, bisogna comunque pubblicizzarla. Se poi il metodo non 
permette di pubblicizzarla, allora va necessariamente gestita.
Se tutto ciò non fosse vero, perchè allora il compilatore mi segnala 
errore (Unhandled exception nel blocco try)?
Grazie!

Le eccezioni o le lanci (e lo dichiari nella clausola throws) o le gestisci.
Le specifiche di Java non permettono l'imboscamento delle eccezioni.
-- 
---
Francesco Galli / Cinghiale Mannaro
Personal: 
http://cinghialemannaro.splinder.com
TMS project: 
http://tms.inera.it

 errore (Unhandled exception nel blocco try)?
Perchè manca il blocco catch.

 
Convieni con me quindi che allora il libro ha preso una cantonata perchè 
ha mancato di dire che, quando non si cattura un'eccezione, bisogna 
comunque pubblicizzarla. Se poi il metodo non permette di 
pubblicizzarla, allora va necessariamente gestita?

 pubblicizzarla, allora va necessariamente gestita?
Francamente non mi pare una cantonata, e' implicito come logica
conseguenza delle due regole. Ovvero, java ti dice che devi gestire le
eccezioni che non propaghi esplicitamente, contemporaneamente ti dice
che l'implementazione di un metodo deve rispettare per contratto le
eccezioni propagate, quello che descrivi è semplicemente una logica
conseguenza.

 pubblicizzarla, allora va necessariamente gestita?
bella red :)
Allora, non ho mai sentito parlare di un blocco try-finally.
Credo cioe' che tu un catch lo debba mettere per forza (anzi, ne sono sicuro!)
Per propagare l'eccezione... mi sa che non hai scampo! come e' gia' stato fatto 
notare, devi rispettare il principio di sostituzione, quindi niente clausola 
throws nel tuo run(). e visto che l'eccezione la devi gestire per forza con un 
catch, ti devi inventare un sistema per far capire al chiamante di run() che 
qlcs e' andato storto (ovviamente, non puoi cambiare il tipo di ritorno!). prova 
con qlc variabile. cioe' che se il run() catcha l'eccezione, setta a true una 
variabile error, che il chiamante controlla subito dopo e prende le sue 
decisioni. boh, l'ho cacciata li, magari non si puo' fare nel tuo caso!
Ciao!
Co

 Co
Il dubbio mi è sorto leggendo un manuale di java (che secondo me ha dato 
troppo per scontato la cosa) e non per un reale problema. Cmq credo si 
possa risolvere elegantemente con una callback.
A presto :)

 Ehehehe esise esiste.
Cioe' posso fare un try-finally senza catch?
Ma ne sei proprio sicuro?

 Ma ne sei proprio sicuro?
E soprattutto, a cosa servirebbe? Non ci arrivo! :-)


Serve a risparmiare codice nel caso in cui in un catch bisogna soltanto 
rilanciare l'eccezione. L'esecuzione si interrompe nel blocco try alla 
prima eccezione lanciata e il metodo finally viene comunque eseguito.

 prima eccezione lanciata e il metodo finally viene comunque eseguito.
E per eseguire codice in ogni caso (eccezione o meno). Il caso tipico è 
la chiusura di qualcosa
try {
   apro connessione
  ...
...
} finally {
  chiudo connessione
}
in questo modo la chiusura avviene sia con eccezione che senza.
bye
DKano

 prima eccezione lanciata e il metodo finally viene comunque eseguito.
si ok, pero' un catch ce lo metti! vuoto, ma ce lo metti giusto?
Cioe', in Java questo mica lo puoi fare:
try {
   metodoCheLanciaEccezioe();
} finally {
   qualcosa();
}
Primo, perche' nessuno, nemmeno il compilatore, sa come gestire l'eccezione che 
lancia il metodo, secondo, perche' anche volendo rimbalzare l'eccezione, non hai 
il riferimento per farlo!
finally {
   throw e; //non ha senso, e non esiste (finally (Exception e) non lo puoi fare)
}
finally {
   throw new Exception();
//potrebbe avere senzo, peccato che il compilatore si incazzi, e a ragione, 
//perche' manca il catch del try
}
Se non ho capito io spiegami che mi incuriosisce

 DKano
ragazzi mi giunge talmente nuova questa che adesso provo a fare una prova sul 
campo e compilo una classe con quel costrutto.

 prova sul campo e compilo una classe con quel costrutto.
Non mi compila (abbiamo tutti ben chiaro che non si puo' mettere throws nella 
signture del metodo vero?)


Secondo Gosgling in un'applicazione ben scritta
dovrebbero essere scritte 10 try...finally per ogni
try...catch: 
http://www.artima.com/intv/solidP.html
Io riesco a vivere anche senza finally, voi ?
Qualcuno ha un esempio open source sotto mano di
codice ben scritto ?
--
Marco

 E soprattutto, a cosa servirebbe? Non ci arrivo! :-)
Potrebbe servire. Il finally verrebbe eseguito anche nel caso in cui si
scatena una eccezione all'interno del blocco catch che viene propagata
tramite la clause throws.
Metti che all'interno del metodo tu voglia fare una operazione di
cleanup quando l'uscita dal metodo è dovuta ad una eccezione.

 
Si si può fare.
No il catch non ci vuole, però il metodo deve dichiarare l'eccezione che 
  viene rilanciata dal try.

 Io riesco a vivere anche senza finally, voi ?
Non sempre, a volte boccheggio.
Ad esempio, se mi trovo ad usare jdbc non pooled e non gestito da
framework esterni (tipo Spring, per intendersi) non saprei come fare
per controllare il rilascio delle risorse.


Partendo da questo presupposto, avevo posto la domanda per il metodo run 
di Thread. Visto che il prototipo non prevede il lancio di un'eccezione, 
nel metodo run() non si potrà mai fare una cosa del genere
try {
}
finally {
}

 signture del metodo vero?)
Facciamo un po' d'ordine:
1) try finally non solo si puň fare, ma č probabilmente piů utile di un
try catch /con finally o meno)
2) le eccezioni non fanno parte della signature di un metodo. Un metodo
puň modificare le eccezioni "tirate" dal metodo di cui fa l'overload,
anche se con una limitazione: non puň aggiungere eccezioni che non siano
parenti di quelle tirate nella superclasse.
Questo vuol dire per esempio che puň non lanciarne per niente, o lanciarne
delle sottoclassi, o lanciarne solo alcune, o un mix di queste.
hth
uL
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it


Ah ok, c'e' qlcn che si prende cura della nostra piccola eccezione allora!
Si certo, ha senso se definisci che il metodo lancia quell'eccezione, ma io 
facevo riferimento al nostro caso in cui questo non si puo' fare.


stesso discorso, il 99% dei finally li uso per operazioni di pulitura (chiusura 
di stream et similia)


try {
}catch(Exception e) {} ?
Se l'eccezione e' OutOfMemoryException, che probabilita'
ho con una finally di chiudere le risorse ?
Rischierei di lanciare una nuova eccezione mentre e' in funzione la
finally.
try{
..
}finally{
try{..}catch(Throwable t){}} ?
Comincio a preferire la prima versione.
--
Marco

 delle sottoclassi, o lanciarne solo alcune, o un mix di queste.
E, per il caso generale, siamo tutti d'accordo.
In questo caso particolare, abbiamo:
public void run() {
try {
   eccezione();
} finally {
   qualcosa();
}
}
il run() e' overload di Thread.run, per il tuo punto 2 non si puo' aggiungere la 
clausola throws.
Per quanto riguarda il blocco try-finally, la logica sarebbe che si esce dal try 
all'occorenza dell'eccezione, si entra nel finally, alla fine del quale, si 
rimbalza l'eccezione al chiamante. L'eccez. non puo' essere buttata fuori, 
quindi si DEVE gestire. Non se ne esce, o metti il catch o niente.
Sicuramente e' una cosa interessante. Red, il libro non fornisce neanche 
un'accenno alla soluzione?

 In questo metodo vorrei non catturare un eccezione ma il compilatore mi 
[CUT]
http://www.forward.com.au/javaProgramming/threadReturnsPackage/ToCatchAThread.html
-- 
Ciao
   Renato
-----
Al telefono:
"Pronto?  Maria, sto tanto male: sono a Bolzano sottozero".
"Caro, io sono sotto uno e sto tanto bene!".
		-- Da it.hobby.umorismo

 un'accenno alla soluzione?
Ma scusate, per pura curiosita', a parte le questioni sintattiche, a chi
diavolo dovrebbe tirare l'eccezione un 3d, al Sistema Operativo ?
Nicola
 
 
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

aaaah, fin li' ci siamo!!!
method A throws AException, BException {
try {
//faqualcosa
b();
//farebbequalcosaltro
} finally {
//faqualcosaltroancora
}
}
method b throws BException {
if (VincentVega.isAntipatico()) throw BException;
}
In questo caso si, la capisco :-) era nel caso dell'esempio che non capivo,
sembrava un metodo per IGNORARE gli errori, cosa che a mio avviso non ha
molto senso. Se proprio vuoi farlo, fallo in modo esplicito, con un catch
block vuoto.


 
Giusto!
Allora:
1) Il costrutto try { ... } finally {  ... } esiste
2) E' chiaro che se dentro il try o il finally un'istruzione lancia 
un'eccezione questa va gestita (o mettendo un throws all'inizio del 
metodo o racchiudendo l'istruzione con un ulteriore try/catch).
3) Il costrutto di cui sopra serve spesso per rilasciare risorse
try {
   risorsa1.open();
   bla bla
} finally {
   risorsa1.close();
}
4) Nel caso specifico essendo il metodo run() di un Thread definito 
nella classe Thread senza eccezioni, implementando il  metodo non si 
possono mettere 'throws'. Il che č fatto apposta, dato che essendo un 
thread a chi dovrebbe lanciarla l'eccezione (come dici giustamente tu)?
La soluzione č, ovviamente, gestire le eccezioni all'interno di run(). 
Come gestirle dipende dal codice e da che eccezioni sono; se sono cose 
bloccanti il thread dovrebbe morire (= uscire da run() ) altrimenti 
riavviarsi, o ignorarle o segnalare nel log e andare avanti ecc.
bye
DKano

 try{..}catch(Throwable t){}} ?
Per esempio, per quanto riguarda jdbc ci hanno pensato.
http://jakarta.apache.org/commons/dbutils/
Offre una closeQuitely() che nasconde l'SQLException.

 DKano
Tutto giusto quello che dite. Ripeto, la questione è nata perchè su un 
manuale Java ho letto che è possibile avere un costrutto
try {
}
finally {
}
senza catch. Questo permette il rilancio automatico dell'eccezione 
sollevata nel blocco try. Il problema è che il libro non specifica che 
il metodo in cui viene messo un blocco try finally del genere, deve 
anche dichiarare l'eccezione che in automatico verrebbe rilanciata! La 
cosa ancora più buffa è che mi è capitato di dover usare questo 
costrutto nel metodo Thread.run(). Quindi, siccome il libro non dice che 
bisogna dichiarare comunque l'eccezione che si vuole rilanciare, io ho 
implementato il metodo run così
public void run() {// Essendo di Thread, il prototipo non può essere diverso
try {
   // codice che solleva un'eccezione
}
finally {
   // codice eseguito cmq
}
// all'uscita rilancio automatico dell'eccezione
in questo caso ovviamente il compilatore segnala errore (giustamente). 
In definitiva il libro ha omesso una cosa molto importante e mi è 
capitato il caso in cui la cosa più ovvia non si potesse fare. Tutto qua!

 finally {
In realtà può farlo se le eccezioni lanciate dal try sono del tipo
runtimeexception che non hanno bisogno di essere dichiarate "to be thrown"
Nel caso specifico del thread vedrai stampata a video la stack trace
-- 
Pietro	- 
http://www.pietroweb.tk
Linux Registered User #304991
Powered by MDK Linux Kernel 2.6.10

 eccezioni.
Con l'eccezione (scusate il gioco di parole) delle runtimeexception che
possono essere lanciate senza bisogno di essere dichiarate.
un blocco try {..} finally {..} è esattamente equivalente a questo:
try {
  ...
} catch (Exception ex) {
  throw ex;
} finally {
  ...


 
Se non ti interessa gestire la situazione che ho delineato prima
e' chiaro che puo' bastare la finally.
--
Marco

 
Si ma così facendo il thread muore e non ne hai il controllo. Se questo 
è accettabile...
bye
DKano

 e lascio scappare l'errore di memoria esaurita.
Giusto per precisare:
- catch trappa l'eccezione, non finally. Se non trappi l'eccezione nel
blocco catch questa viene regolarmente propagata anche in presenza di
finally.
- se lasci propagare l'errore, le reference locali alle risorse non le
vedi più. Quindi non capisco come tu possa chiudere lo statement o
rilasciare la connessione "in un secondo momento".
- I due motivi in cui contesti finally non sono consistenti.

 
Credo che non ci siamo intesi sull'accezione di trap.
--
Marco