Classe Fantasma? [Concluído]  XML
Índice dos Fóruns » Java Avançado
Autor Mensagem
RafaelRio
Java Ninja
[Avatar]

Membro desde: 05/09/2006 06:52:42
Mensagens: 255
Localização: São Paulo
Offline

Trabalhando com o FindBugs, eu descobri uma classe no meu projeto que nem eu sabia que existia! (sic)

Para os que não sabem, FindBugs é uma ótima ferramenta de detecção de erros (http://findbugs.sourceforge.net/).

Entre os bugs, há um que não consigo resolver, justamente por não ter nunca criado a classe em que há o erro reportado:
SnVI: core.venda.TableProdutoModel is Serializable; consider declaring a serialVersionUID

Para ficar claro, as classes que estão no pacote core.venda:
TabelaPedidoProduto.java
TabelaPedidoProduto$TableProdutoModel.java
VPedido.java
VPedidoFiltroPesquisa.java
VPedido_Form.java
VToolbar


A primeira coisa que pensei foi num bug do próprio FindBugs; nem considerei falso positivo porque não escrevi essa classe. Mas, por curiosidade, rodando o serialver para core.main.TableProdutoModel, eu obtenho um serialVersionUID ( 4160808804131702876L). Isso significa que o JDK achou a classe core.venda.TableProdutoModel!

serialver é a ferramenta inclusa no JDK responsável por auxiliar na criação de serialVersionUID únicos.

Alguém tem alguma idéia do que possa ser essa classe?

Rafael Fiume.
Yes, Nós Temos Bananas

Sun Certified Programmer for the Java Platform, Standard Edition 6
Sun Certified Web Component Developer for the Java Platform, Enterprise Edition 5

Nullius in verba.
"A palavra de nenhum homem será a final."
Lema da Royal Society, associação de cientistas de Londres, em 1660. Entre os seus membros e presidentes esteve Isaac Newton.
[Email]
fmeyer
Moderador
[Avatar]
Membro desde: 22/02/2005 17:26:29
Mensagens: 1583
Localização: Sao Paulo
Offline

[editado] por estar dormindo e nao ler o post direito

Fernando Meyer http://fernandomeyer.com
[Email] [WWW]
isneiqui
Thread.start()
[Avatar]

Membro desde: 22/04/2004 17:50:44
Mensagens: 38
Localização: São Paulo/SP
Offline

será que essa TableProdutoModel não é uma classe interna da TabelaPedidoProduto?

abs,

MS IE User: BrainNotFoundException.
[MSN] [ICQ]
RafaelRio
Java Ninja
[Avatar]

Membro desde: 05/09/2006 06:52:42
Mensagens: 255
Localização: São Paulo
Offline

Eu tenho a classe core.venda.TabelaPedidoProduto$TableProdutoModel.java, que é a classe interna a qual você se referiu. Não há problemas nessa classe.

O FindBugs é bem claro e se refere à classe core.venda.TableProdutoModel. Ou seja, se refere a uma classe que não é interna. Um detalhe importante que não mencionei sobre o FindBugs é que ele inspeciona os bytecodes, e não o codigo-fonte.

[EDITADO] Parece que o JDK está criando essa classe core.venda.TableProdutoModel.
Se eu digito


e


eu obtenho duas serialVersionUID diferentes:
-1177104958417288601L, na primeira; e
4160808804131702876L para a "classe fantasma".

As duas existem e são diferentes. Queria mesmo entender o que está acontecendo aqui.

Rafael Fiume.
Yes, Nós Temos Bananas

Sun Certified Programmer for the Java Platform, Standard Edition 6
Sun Certified Web Component Developer for the Java Platform, Enterprise Edition 5

Nullius in verba.
"A palavra de nenhum homem será a final."
Lema da Royal Society, associação de cientistas de Londres, em 1660. Entre os seus membros e presidentes esteve Isaac Newton.
[Email]
davidbuzatto
Moderador
[Avatar]

Membro desde: 07/08/2004 23:47:57
Mensagens: 4013
Localização: Vargem Grande do Sul - SP
Offline

Como assim parece?

É claro que vaiu ser gerado o .class de uma classe interna.

Posso até estar falando besteira, mas será que no primeiro serialver q vc ta usando ele num ta pegando da classe TabelaPedidoProduto?

Seja educado. Agradeça quem te ajudou. Não custa nada.
Dúvidas de Java? Utilize o fórum! Não respondo via MP.

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Fowler)
"A vida é um escândalo, e no final dá sempre errado. O que humaniza o homem é o fracasso."

http://davidbuzatto.com.br | GitHub | uHunt | CV Lattes | Last.fm
[WWW]
RafaelRio
Java Ninja
[Avatar]

Membro desde: 05/09/2006 06:52:42
Mensagens: 255
Localização: São Paulo
Offline

Como eu já havia dito:
RafaelRio wrote:Eu tenho a classe core.venda.TabelaPedidoProduto$TableProdutoModel.java, que é a classe interna a qual você se referiu. Não há problemas nessa classe.

O FindBugs é bem claro e se refere à classe core.venda.TableProdutoModel. Ou seja, se refere a uma classe que não é interna.


Boa questão que você levantou aqui:
davidbuzatto wrote:será que no primeiro serialver q vc ta usando ele num ta pegando da classe TabelaPedidoProduto?

Não sei se ele está acessando core.venda.TabelaPedidoProduto, mas sim, o serialVersionUID que ele gera para a classe (que eu não fiz!) core.venda.TableProdutoModel tem o mesmo valor:
-1177104958417288601L

Acho que entedi sua linha de raciocínio. Se o serialver está acessando core.venda.TabelaPedidoProduto ao invés de core.venda.TableProdutoModel (a fantasma), então é um bug do serialver, essa ultima classe não existe e todos foram felizes para sempre.

Mas, não parece ser o caso.
1) uma ferramenta inclusa no JDK não teria um erro tão tosco desses (eu quero acreditar nisso!);
2) o FindBugs, que não tem nada a ver com o serialver, também está acessando essa classe "fantasma" - que na verdade não é fantasma porque ela estã lá nos bytecodes, mas não está nos arquivos .class. muito menos nos .java.

Rafael Fiume.
Yes, Nós Temos Bananas

Sun Certified Programmer for the Java Platform, Standard Edition 6
Sun Certified Web Component Developer for the Java Platform, Enterprise Edition 5

Nullius in verba.
"A palavra de nenhum homem será a final."
Lema da Royal Society, associação de cientistas de Londres, em 1660. Entre os seus membros e presidentes esteve Isaac Newton.
[Email]
Sami Koivu
Virtual Machine Man
[Avatar]

Membro desde: 16/09/2004 09:49:27
Mensagens: 574
Localização: Curitiba-PR
Offline

Olá,

Concordo que o serialver dificilmente teria um bug desses.

Fiz uns testes aqui. Se eu tenho a seguinte classe (com a classe interna):



O resultado é seguinte:


serialver -classpath . core.venda.TableProdutoModel
Class core.venda.TableProdutoModel not found.


Mas se dentro do arquivo TabelaPedidoProduto.java eu também defino outra classe TableProdutoModel, mais ou menos assim:



Esses dois comandos dão o mesmo resultado:

serialver.exe -classpath . core.venda.TabelaPedidoProduto$TableProdutoModel
core.venda.TabelaPedidoProduto$TableProdutoModel:
static final long serialVersionUID = 7197658479874817205L;

serialver.exe -classpath . core.venda.TabelaPedidoProduto.TableProdutoModel
core.venda.TabelaPedidoProduto.TableProdutoModel:
static final long serialVersionUID = 7197658479874817205L;


Bom. Não acredito em fantasmas. Eu acho que em algum lugar no seu classpath você tem essa classe.

Uma coisa que você pode fazer, é testar com o comando javap que lista os campos e métodos de uma classe.

Com meu teste, ele dá os seguintes resultados:


javap.exe -classpath . core.venda.TableProdutoModel
Compiled from "TabelaPedidoProduto.java"
class core.venda.TableProdutoModel extends java.lang.Object implements java.io.Serializable{
int a;
short s;
core.venda.TableProdutoModel();
}



javap.exe -classpath . core.venda.TabelaPedidoProduto.TableProdutoModel
Compiled from "TabelaPedidoProduto.java"
class core.venda.TabelaPedidoProduto$TableProdutoModel extends java.lang.Object
implements java.io.Serializable{
float f;
double d;
core.venda.TabelaPedidoProduto$TableProdutoModel();
}



[]s,
Sami

(Slightly) Random Broken Thoughts on Java Security
[Email] [WWW] [Yahoo!] [MSN]
Sami Koivu
Virtual Machine Man
[Avatar]

Membro desde: 16/09/2004 09:49:27
Mensagens: 574
Localização: Curitiba-PR
Offline

Compiled from "TabelaPedidoProduto.java"


Inclusive, dependendo do compilador (e as opções definidas), o nome do arquivo fonte é incluído no .class. No seu caso em particular, essa informação seria interessante. Nota que no meu teste, ele dá o mesmo nome para ambas classes (que faz sentido, sendo que ambas classes foram definidas nesse arquivo).

(Slightly) Random Broken Thoughts on Java Security
[Email] [WWW] [Yahoo!] [MSN]
RafaelRio
Java Ninja
[Avatar]

Membro desde: 05/09/2006 06:52:42
Mensagens: 255
Localização: São Paulo
Offline

RafaelRio wrote:1) uma ferramenta inclusa no JDK não teria um erro tão tosco desses

Quem? Eu disse isso?! Eu não!!
Então, vamos testar:


O resultado: -1177104958417288601L

davidbuzatto wrote:será que no primeiro serialver q vc ta usando ele num ta pegando da classe TabelaPedidoProduto?

Chutou, e a bola foi no ângulo!

Para qualquer classe que seja interna não só do arquivo .java, mas que também esteja literalmente dentro da classe com o nome do arquivo (as classes separadas por "$"), é gerado o mesmo serialVersionUID. Só que o serialver nem verifica se a classe existe ou não; já devolve na lata o seralVersionUID, mesmo que a classe interna nem exista, ao invés de um "Class not found".

Sami Koivu wrote:Mas se dentro do arquivo TabelaPedidoProduto.java eu também defino outra classe TableProdutoModel...

Tinha escrito antes que não tinha o arquivo .java. Mas e quanto ao .class? Fui verificar e la estava ele, o core.venda.TableProdutoModel.
O problema era mesmo esse, criei as duas classes dentro do mesmo arquivo e estava procurando por core.venda.TabelaPedidoProduto$TableProdutoModel, quando o que é gerado pelo JDK é core.venda.TableProdutoModel. O serialver me deu corda, por não dizer que a classe não existe, e eu acabei me enrolando todo.

Sami Koivu wrote:Bom. Não acredito em fantasmas.

Então, concluindo: não acreditem em fantasmas.



Rafael Fiume.
Yes, Nós Temos Bananas

Sun Certified Programmer for the Java Platform, Standard Edition 6
Sun Certified Web Component Developer for the Java Platform, Enterprise Edition 5

Nullius in verba.
"A palavra de nenhum homem será a final."
Lema da Royal Society, associação de cientistas de Londres, em 1660. Entre os seus membros e presidentes esteve Isaac Newton.
[Email]
 
Índice dos Fóruns » Java Avançado
Ir para:   
Powered by JForum 2.1.8 © JForum Team