Ué, catch não captura a Exception?  XML
Índice dos Fóruns » Java Avançado
Autor Mensagem
renatosilva
GUJ Master

Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline

EDITADO

Sinistro o bagulho pessoal. Tô fazendo uma classe pra facilitar serialização. Tem uma classe abstrata Serializer<T> e duas implementações, uma delas é XMLSerializer<T>.

O problema é o seguinte: eu serializei um objeto para XML, depois abri o arquivo e mudei o nome da classe, depois tentei desserializar. O objetivo era testar se a classe ia fazer o comportamento certo, que seria retornar null e guardar a exception lançada. Mas isso não acontece. Nessa implementação que usa java.beans.XMLDecoder, ao chamar o readObject() desta classe é lançada uma ClassNotFoundException.

Até aí tudo bem, mas o método não tem a exceção na assinatura (se faz parte), e o catch simplesmente não funciona!!!

Arguém majuda faizfavôr!!!

Classe probemárdiga XMLSerializer<T>:



Essa classe aqui é a classe abstrata Serializer<T>, não sei se ela teria algo errado:



Essa é a classe de teste:



Essa é a saída da classe de teste. Vejam que o XML aparece às vezes no meio das exceptions, isso parece código em multi-thread:




Helpem me plis!
Fabricio Cozer Martins
GUJ Ranger
[Avatar]

Membro desde: 08/05/2004 10:22:03
Mensagens: 935
Localização: Salvador/Brasil
Offline

sem o printStackTrace fica sombrio ...

Fabrício Cozer Martins
Analista de Sistemas
Bacharel em Ciência da Computação da UFBa
Sun Certified Programmer for Java 2 Platform 1.4
Sun Certified Web Component Developer for J2EE 1.4
[MSN] [ICQ]
renatosilva
GUJ Master

Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline

Pois é, como vou printar o stack trace se nem catcheia!!!!

Não lembro como mas tinha conseguido ver, a exceção emerge no XMLDecoder.readObject() e origina-se das suas profundezas, é tudo lá dentro. Só que esse método não lança exceção segundo o código, por isso não consigo tratar pois o compilador não deixa, mas quando roda esse método lança sim!!!
louds
Moderador
[Avatar]

Membro desde: 29/04/2003 23:09:15
Mensagens: 4061
Localização: São Paulo
Offline

Será que não é um Error não?

http://www.kumpera.net/blog/
http://www.mono-project.com/
"Each individual should work for himself. People will not sacrifice themselves for the company. They come to work at the company to enjoy themselves."
Soichiro Honda
[ICQ]
006024
Smalltalk

Membro desde: 03/04/2006 19:39:36
Mensagens: 2
Offline

Meu amigo, tenta colocar throw new Exception (blablablabla) por exemplo...
Acho que deve resolver seu problema...
ciczan
JavaGuru
[Avatar]

Membro desde: 22/12/2004 12:57:21
Mensagens: 227
Localização: Curitiba -PR
Offline

A uns tempos eu tive um problema desses, com essa mesma ClassNotFoundException, e o que acontecia era que a exceção estava sendo lançada de outra Thread, porque o classloader era chamado assim... sei lá, não me pergunte por que...

Dei uma procurada na internet e só o que encontrei foi isso aqui:
http://dev.eclipse.org/mhonarc/lists/gef-dev/msg00469.html

A sugestão (segue abaixo) não parece fazer muito sentido, mas pelo jeito funcionou:

You can add the following expression: Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
before using the nofouned class
[MSN]
velo
GUJ Ranger
[Avatar]

Membro desde: 19/02/2004 18:23:55
Mensagens: 797
Localização: Jaraguá do Sul - SC
Offline



Esse catch é pegador....


VELO

Use o melhor:

Linux para servidores
Macintosh para gráficos
Palm para mobilidade
Windows para jogar paciência

SCJP 5
[Email] [MSN] [ICQ]
renatosilva
GUJ Master

Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline

louds wrote:Será que não é um Error não?


Não, ClassNotFoundException é exatamente uma Exception (checked).

006024 wrote:Meu amigo, tenta colocar throw new Exception (blablablabla) por exemplo...


Onde?

velo wrote:

Esse catch é pegador....


VELO


Dá uma olhada no meu post, eu coloquei isso e mesmo assim nada...

ciczan wrote:A uns tempos eu tive um problema desses, com essa mesma ClassNotFoundException, e o que acontecia era que a exceção estava sendo lançada de outra Thread, porque o classloader era chamado assim... sei lá, não me pergunte por que...

Dei uma procurada na internet e só o que encontrei foi isso aqui:
http://dev.eclipse.org/mhonarc/lists/gef-dev/msg00469.html

A sugestão (segue abaixo) não parece fazer muito sentido, mas pelo jeito funcionou:

You can add the following expression: Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
before using the nofouned class


Pô cara, minha cabeça é meio travada com esses lances de classloader. Mas li oi link, o que seria "classe não encontrada"? Seria na chamada XMLDecoder.readObject()? Assim que puder vou testar isso...

Isso parece até bug, onde já se viu, catch que não catcheia o catcheável
renatosilva
GUJ Master

Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline

Pessoal, eu andei testando e a única conclusão que consegui chegar é que isso é um bug, se é que podemos chamar assim.

Eu cheguei a testar a dica do Ciczan antes da chamada XMLDecoder.readObject(), mas não rolou.

O que eu acho que acontece é que exception nenhuma é lançada, apenas uma mensagem é exibida na tela com o seu nome.

A solução gambiarra que achei foi manter System.err como null enquanto o método problemático roda. Não pude debugar a java.beans.XMLDecoder também, parece que algum parser SAX surge das profundezas e usa o System.err...

Alterei o método deserialize da XMLSerializer assim:



O que acham?? É meio gambiarra, o mais certo acho que era não usar System.err e passar a exception prea frente (pra mim)...

TedLoprao
Virtual Machine Man
[Avatar]

Membro desde: 09/05/2003 00:32:03
Mensagens: 607
Offline

E ae Renato3110!!

Cara, uma pergunta. O q tu queres fazer neste caso de exceção?

Na verdade você precisa usar um java.beans.ExceptionListener para pegar os erros durante o parse. O ExceptionListener default só imprime aquelas mensagens no System.err, mas vc pode implementar o seu:



Vê se isso te ajuda!

Falou

Rodrigo Klein
----------------------------------------------------
Java is the best
renatosilva
GUJ Master

Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline

Pô Rodrigo, valeu pela dica. Muito esquisito isso ai, não acha? Vou testar depois, valeuz...
velo
GUJ Ranger
[Avatar]

Membro desde: 19/02/2004 18:23:55
Mensagens: 797
Localização: Jaraguá do Sul - SC
Offline

Kra, c tem eclipse aí?

VELO

Use o melhor:

Linux para servidores
Macintosh para gráficos
Palm para mobilidade
Windows para jogar paciência

SCJP 5
[Email] [MSN] [ICQ]
ZehOliveira
GUJ Ranger

Membro desde: 12/12/2003 22:13:49
Mensagens: 964
Localização: Maceio-AL
Offline

tedloprao wrote:Na verdade você precisa usar um java.beans.ExceptionListener para pegar os erros durante o parse. O ExceptionListener default só imprime aquelas mensagens no System.err...

Quem será que teve essa grande idéia hein?
renatosilva
GUJ Master

Membro desde: 16/12/2004 17:09:19
Mensagens: 1787
Offline

velo wrote:Kra, c tem eclipse aí?

VELO


É o Eclipse que tô usando...

ZehOliveira wrote:
tedloprao wrote:Na verdade você precisa usar um java.beans.ExceptionListener para pegar os erros durante o parse. O ExceptionListener default só imprime aquelas mensagens no System.err...

Quem será que teve essa grande idéia hein?


Também não achei lá muito legal não, pelo menos se esse argumento fosse obrigatório... Se não fosse o fórum eu nem ia ficar sabendo, nem tive como testar ainda...

Aliás, por falar nisso queria saber a opinião de vocês porque eu também nessas classes procuro fugir do esquema convencional de exceções.

Acho muito absurdo obrigar a tratar a exceção em cada chamada de read() ou write(). Também não acho legal uma runtime exception, simplesmente porque em caso de erro não há tratamento e o programa termina!

O cenário que imagino é que em alguns casos não será importante tratar o erro, mas em outros sim. Eu pensei numa forma que não obriga nem uma coisa, nem outra, deixando que a situação determine. Na prática seria o mesmo efeito de uma RuntimeException, só que silenciosa caso não seja tratada.

É o seguinte, o write(T) retorna um booleano que indica sucesso ou falha na serialização. Se você se interessar em tratar o erro você pode, em caso de falha, obter a exceção gerada.

No read() o retorno null não significa erro, você pode usar succeeded() ou failed() para verificar erro e depois obter a exceção gerada, ou mesmo apenas a sua mesnagem que é mais prático.

Ficaria assim:



Feio? Bonito?
Filipe Sabella
GUJ Expert

Membro desde: 12/03/2003 11:25:57
Mensagens: 4680
Offline

Pera, você acha ruim tratar exceção mas não acha ruim tratar um boolean? hehe é a mesma coisa cara.


Former LIPE.
[ICQ]
 
Índice dos Fóruns » Java Avançado
Ir para:   
Powered by JForum 2.1.8 © JForum Team