Classe Fantasma? [Concluído]

8 respostas
RafaelRio

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:
[color=darkred]SnVI: core.venda.TableProdutoModel is Serializable; consider declaring a serialVersionUID[/color]

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?

8 Respostas

fmeyer

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

isneiqui

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

abs,

RafaelRio

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

serialver core.venda.TabelaPedidoProduto$TableProdutoModel

e

serialver core.venda.TableProdutoModel

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.

davidbuzatto

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?

RafaelRio

Como eu já havia dito:

RafaelRio:
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:
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.
Sami_Koivu

Olá,

Concordo que o serialver dificilmente teria um bug desses.

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

package core.venda;

import java.io.Serializable;

public class TabelaPedidoProduto implements Serializable {
	int a;
	String b;

	static class TableProdutoModel implements Serializable {
		float f;
		double d;
	}
}

O resultado é seguinte:

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

package core.venda;

import java.io.Serializable;

public class TabelaPedidoProduto implements Serializable {
	int a;
	String b;

	static class TableProdutoModel implements Serializable {
		float f;
		double d;
	}
}

class TableProdutoModel implements Serializable {
	int a;
	short s;
}

Esses dois comandos dão o mesmo resultado:

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:

[]s,
Sami

Sami_Koivu

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).

RafaelRio

RafaelRio:
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:

serialver core.venda.TabelaPedidoProduto$AbacaxiNaoFazPipi

O resultado: -1177104958417288601L

davidbuzatto:
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”.

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.

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

Criado 18 de novembro de 2006
Ultima resposta 22 de nov. de 2006
Respostas 8
Participantes 5