Serialização de classes

15 respostas
E

Boa tarde a todos.
Estive analisando alguns artigos sobre versionamento de classes utilizando Serializable e surgiu algumas dúvidas, sendo elas:

  • Quando serializo (se esta for a tradução) uma classe, quais são os possíveis impactos que esta virá a sofrer ao utilizar esta interface?

  • Se há um impacto que se faça necessário criar controles para gerenciá-la, quais os mais necessários?

  • Com uma classe com essas características, é possível instanciá-la normalmente como uma classe default para aplicações para web ?

Agradeço a todos pela atenção.
Ederson.

15 Respostas

RodrigoSol

Ué… Serializar Classes? Não seria Objetos?

versionamento de classes com serialização? isso é novo pra mim.
Pode mandar os links?

E

Ops, foi mal.
É serialização de objetos mesmo, desculpe a falha.

RodrigoSol

Sem problemas Ederson.

Gostaria de te ajudar e já fiz alguns trabalhos usando serialização, porem não entendi bem suas duvidas.

Será que você pode tentar explicar novamente?

E

Boa tarde Rodrigo Sol.

A questão é a seguinte:
Na atual empresa onde estou prestando serviço, estão querendo criar um mecanismo que registre e possibilite visualizar as versões das classes para garantir o ambiente de produção.
Mas isso eu também conseguiria criando um atributo da classe com a versão desta e a buscaria com um método get, mas não é isso o que querem. Querem criar algo que, mesmo que a classe estaja enfrentando problemas, seja possível visualizar esta informação sem necessidade de instanciar o objeto desta classe.
Eu estava observando que, tornando uma classe “seriável”, eu consigo obter a informação de um atributo específico através do comando [i]serialver[/i].
A abertura do tópico se fez necessário pois, como é a primeira vez que trabalho com esta modalidade de objetos e também por dúvidas quanto a consequüencia de deixá-la assim, principalmente em um ambiente web.
Espero ter clareado suas idéias.

Att.
Ederson

E

Olá RodrigoSol.

Acabei de fazer um teste com uma classe abaixo ao main e surgiu uma exceção. Acho que abandonarei esta solução e procurarei outra.

Exception in thread "main" java.lang.NoClassDefFoundError: Registro01 (wrong nam
e: br/com/itautec/registros/Registro01)
        at java.lang.ClassLoader.defineClass0(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:537)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:12
3)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:219)
        at sun.tools.serialver.SerialVer.resolveClass(SerialVer.java:189)
        at sun.tools.serialver.SerialVer.serialSyntax(SerialVer.java:161)
        at sun.tools.serialver.SerialVer.main(SerialVer.java:270)

Vc ou mais alguém conhece uma outra solução?

Abraços.
Ederson.

RodrigoSol

Será que um CVS não resolve seu problema?
http://www.guj.com.br/forum/viewtopic.php?t=8129&highlight=cvs

Se você quiser e tiver $$ pode tentar também o Rational Clear Case
http://www-306.ibm.com/software/awdtools/clearcase/

Esse ferramentas vão te garantir todo o controle de vesão da sua aplicação…

o clear case eu conheço bem, e posso te falar que tem monte de recursos legais que acredito também existam nas outras ferramentas open source.

cv1

Essas ferramentas vão te garantir todo o controle de versão DO CODIGO FONTE da sua aplicação… o que nao me parece ser bem o que o Ederson esta precisando.

Ederson, se eu entendi bem o problema, vcs possuem varias versoes de varios deployments diferentes da mesma aplicacao em diversos servidores, e querem garantir compatibilidade binaria entre os objetos, pra que a coisa possa funcionar redondinha num cluster, por exemplo, certo?

Se for esse o caso, de uma olhada na especificacao da serializacao - existe um campo, chamado serialVersionUID, que te deixa marcar os .class com uma versao - mas vc tem que se lembrar sempre de atualizar essa versao, especialmente quando fizer mudancas que quebram a compatibilidade binaria do codigo (nomes e tipos de variaveis, assinatura de metodos, basicamente, todo o contrato publico da classe, e tudo que for serializavel).

Eh algo beeeeem chatinho de fazer, mas perfeitamente possivel. So requer uma boa dose de paciencia e um controle rigido dos builds e do codigo fonte - e, pra este ultimo, CVS e similares sao obrigatorios :wink:

RodrigoSol

:oops: Foi mal… não tinha entendido que você queria garantir a compatibilidade binaria.

tem um projeto no sourceforge mas ainda não tem release:

E

Olá CV.
Cheguei a verificar esta especificação e cheguei a fazer testes também, mas acho que não será necessário tanto controle assim, vou dar um exemplo mais sutil pra facilitarmos as coisas:

Existe um código A1 que está funcionado perfeitamente, e por alguma necessidade do cliente, foi necessária uma modificação em um determinado ponto. Com isso eu gerei uma nova versão de código fonte e posteriormente de código unicode, que podemos chamar de A2.
Por alguma negligência, foi colocado no servidor o código A1 e o sistema continou executando todas as tarefas antigas, pra loucura do cliente.
Então qual é a idéia: acessando de alguma forma a classe, eu saberia se ela é a A1 ou A2, e assim facilitaria o trabalho de manutenção da aplicação.

Com a utilização da especificação, criei uma classe básica, tipo HelloWorld para verificar a funcionalidade, e realmente, ao utilizar um comando que existe na %JAVA_HOME%in chamado serialver. Um exemplo:

C:ferramentaseclipseworkspaceframework>serialver Iniciar1
Iniciar1:    static final long serialVersionUID = 100L;

Se, ao implementar a interface Serializable e colocar este atributo em todas as classes (acesso a banco, servidor, servlets, exceções, etc) e não causar uma mudança de código muito significativa, meus problemas acabaram, mas se isso vier a complicar um pouco, eu não sei se chega a ser válido.

Grato a todos.
Ederson.

cv1

Me corrijam se eu estiver errado, mas eu acho que vc nao precisa marcar uma classe como Serializable pra ter o serialVersionUID nela… o problema aqui eh que marcar uma classe nao serializavel (uma Thread, por exemplo) como tal pode causar desastres se vc tentar serializa-la mais pra frente… alem de deixar o codigo esquisito (implements Runnable, Serializable!?) :smiley:

E

Olá CV.
Infelizmente deixar a classe não seriável não permite que eu acesse este atributo, como mostra o código abaixo:

C:ferramentaseclipseworkspaceframework>serialver Iniciar1
Class Iniciar1 is not Serializable.

Vou tentar uma solução mais simples, como registro de logs para visualizar estas informações.

Muito agradecido pela ajuda.
Ederson.

Ps: To devendo uma caixa de bombons para vcs.

cv1

Hmm, que pena… bem que podia ter serialVersionUID em todas as classes :frowning:

Bom, mas jah que eh assim, vc pode colocar um “private static final byte versao” em todas as classes, e…

Putz, pensando bem, melhor nao fazer nada disso. Voce esta combatendo o sintoma, nao o problema - se teu cliente te ligou xingando pq entrou a versao errada no ar, o problema eh que entrou uma versao errada, nao o fato de existir uma versao errada… tem certeza que o seu esquema de deployment esta o melhor possivel?

E

Bom dia CV.
Ainda estamos em fase de estudos, não há nada desenvolvido ainda. Por isso que estou analisando uma solução para ser utilizada em todo a aplicação quando esta for inicializada.
Vou montar um log diário que registra todas as classes acessadas e suas respectivas versões. Acho que isso resolve os meus problemas.

Muito obrigado.
Ederson.

louds

Não é mais facil incluir no processo de build a geração de 1 arquivo de versão?

Se tive usando ant, manda gerar um arquivo de properties colocando o timestamp do build. Gera um arquivo assim:

[quote]
build.version = 1.2.65
build.time = 23/01/2004 12:00:01 GMT -3
build.responsible = cv ([email removido]) [telefone removido]

[quote]

Então é só criar uma classe que te da acesso a essa informação:

class VersionControl {
    static Properties props = new Properties();
    static { //todo colocar try/catch p/ IOException
       prop.load(Thread.currentThread().getContextClassLoader().
getResourceAsStream("version.properties"));
     } 
public static String getModuleVersion() {
     return prop.getProperty("build.version");
}

public static String getModuleBuildTime() {
     return prop.getProperty("build.time");
}

public static String getBuildResponsible() {
     return prop.getProperty("build.responsible");
}

}

Isso deve resolver seu problema. Com o bonus do cliente ter acesso mais facil a quem esporrar se for feito caca.

Nota: Essa classe explicitamente e concientemente fere a especificação de EJB. Isso torna possivel verificar as versões em uso em cada deployment independentement.

E

Muito obrigado pela idéia Louds.

Abraços.
Ederson

Criado 21 de janeiro de 2004
Ultima resposta 23 de jan. de 2004
Respostas 15
Participantes 4