Pergunta

Atualmente estou trabalhando em um projeto que precisa persistir qualquer tipo de objeto (de que a implementação não temos qualquer controle) para que esses objetos poderiam ser recuperados mais tarde.

Não podemos implementar um ORM, porque não podemos restringir os usuários de nossa biblioteca em tempo de desenvolvimento.

Nossa primeira alternativa era serializá-lo com a serialização padrão Java, mas tivemos um monte de problemas recuperar os objetos quando os usuários começaram a passar diferentes versões do mesmo objeto (atributos alterados tipos, nomes, ...).

Temos tentado com a classe XMLEncoder (transforma um objeto em um XML), mas descobrimos que há uma falta de funcionalidade (não suporta enumerações, por exemplo).

Finalmente, nós também tentou JAXB mas isso impor nossos usuários para anotar suas classes.

Qualquer boa alternativa?

Foi útil?

Solução

A coisa mais fácil para você fazer ainda é a utilização de serialização, IMO, mas colocar mais pensou no formulário serializado das classes (que você realmente deveria fazer de qualquer maneira). Por exemplo:

  1. Explicitamente definir o SerialUID.
  2. Definir a sua própria forma serializada se for o caso.

O formulário serializado é parte da classe API e pensamento cuidadoso deve ser colocado no seu design.

Eu não vou entrar em muitos detalhes, uma vez que praticamente tudo que eu disse vem de Effective Java. Eu vou em vez disso, encaminhá-lo para que, especificamente, os capítulos sobre a serialização. Ele avisa sobre todos os problemas que você está correndo para, e fornece soluções adequadas para o problema:

http://www.amazon.com/Effective-Java-2nd-Joshua- Bloch / dp / 0321356683


Com o que disse, se você ainda está pensando em uma abordagem não-serialização, aqui estão alguns:

XML triagem

Como muitos tem fora pontas é uma opção, mas eu acho que você ainda vai correr para os mesmos problemas com compatibilidade com versões anteriores. No entanto, com triagem XML, você espera alcançar estes de imediato, uma vez que algumas estruturas podem fazer algumas verificações para você durante a inicialização.

Conversão de / para YAML

Esta é uma idéia que tenho sido brincando com, mas eu realmente gostei do formato YAML (pelo menos como um formato toString personalizado ()). Mas, realmente, a única diferença para você é que você estaria triagem para YAML em vez de XML. A única vantagem é que que YAML é um pouco mais legível do que XML. As mesmas restrições se aplicam.

Outras dicas

É 2011, e em um RESTO classe comercial serviços web projetar usamos os seguintes serializers para os clientes oferecem uma variedade de tipos de mídia:

  • XStream (para XML, mas não para JSON)
  • Jackson (para JSON)
  • Kryo (a rápida e compacta formato de serialização binária)
  • Sorriso (um formato binário que vem com Jackson 1.6 e posteriores).
  • Java serialização de objetos.

Nós experimentamos com outros serializers recentemente:

  • SimpleXML parece sólida, é executado em 2x a velocidade do XStream, mas requer um pouco demais de configuração para o nosso situação.
  • YamlBeans tinha um par de erros.
  • SnakeYAML tinha um pequeno bug relativos a datas.

Jackson JSON, Kryo, e Jackson Sorriso foram significativamente mais rápido do que o bom e velho Serialização de Objetos Java, em cerca de 3x para 4.5x. XStream está no lado lento. Mas estas são todas as escolhas sólidas neste momento. Nós vamos continuar a acompanhar os outros três.

http://x-stream.github.io/ é bom, por favor, tome um olhar para ele! Muito conveniente

de que a implementação não temos qualquer controle

A solução é não faça isso . Se você não tem o controle de implementação de um tipo que você não deve ser serializadas-lo. Fim da história. serialização Java fornece serialVersionUID especificamente para o gerenciamento incompatibilidades serialização entre diferentes versões de um tipo. Se você não controlar a implementação você não pode ter certeza de que IDs estão sendo alterados corretamente quando um desenvolvedor muda uma classe.

Vejamos um exemplo simples de um 'ponto'. Ele pode ser representado por qualquer uma cartesiano ou um sistema de coordenadas polares. Seria proibitivo custo para você construir um sistema que poderia lidar dinamicamente com esses tipos de correções -. Ele realmente tem que ser o desenvolvedor da classe que desenha a serialização

Em suma, é o seu design que é errado -. Não a tecnologia

O Google surgiu com um protocolo binário - http://code.google.com/apis/ protocolbuffers / é mais rápido, tem uma carga menor em comparação com XML -. que já foi sugerido como alternativa

Uma das advanteages de buffers de protocolo é que ele pode trocar informações com C, C ++, Python e Java.

Tente serialização para JSON com Gson por exemplo.

Além disso, um JDK serialização muito rápido substituto: http://ruedigermoeller.github.io/fast-serialization/

Se a velocidade de serialização é importante para você, então há uma referência abrangente de serializers JVM aqui:

Pessoalmente, eu uso Fame muito, uma vez que apresenta interoperabilidade com Smalltalk (VW e Squeak) e Python. (Disclaimer: Eu sou o principal contribuinte do projeto Fame.)

Betwixt é uma biblioteca bom para serialização de objetos - mas não vai ser uma espécie automática de coisa. Se o número de objetos que você tem que serialize é relativamente fixo, esta pode ser uma boa opção para você, mas se o seu 'cliente' vai estar jogando novas classes em você o tempo todo, pode ser mais esforço do que vale a pena ( definitivamente mais fácil do que XMLEncoder para todos os casos especiais, embora).

Outra abordagem é exigir que o seu cliente para fornecer os arquivos .betwixt apropriados para qualquer objetos que atirar em você (que efetivamente offloads a responsabilidade para eles).

Long e curta - serialização é duro - não há completamente cérebro abordagem morto para ele. serialização Java é tão perto de uma solução morte cerebral como eu já vi, mas como você encontrou, uso incorreto do valor uid versão pode quebrá-lo. serialização Java também requer o uso do marcador interface 'Serializable', então se você não pode controlar sua fonte, você é tipo de fora da sorte em que um.

Se a exigência é realmente tão árdua como você descreve, você pode ter que recorrer a algum tipo de AEC (Byte modificação do código) sobre os objetos / aspectos / whatever. Isso está ficando meio fora do âmbito de um projeto de desenvolvimento pequeno, e para o reino do Hibernate, Casper ou um ORM ....

Outra idéia: Use cache. Caches fornecer controle muito melhor, escalabilidade e robustez para a aplicação. Ainda precisa serialize, embora, mas a gestão torna-se muito mais fácil com dentro de um quadro serviço de cache. Cache pode ser mantido na memória, disco, banco de dados ou matriz - ou todas as opções - com um ser excesso, stand by, fail-over para o outro. Comuns JCS e Ehcache são duas implementações de Java, este último é uma solução livre empresa até 32 GB de armazenamento (aviso: I não funcionam para ehcache ;-)).

SBE é uma biblioteca criada para rápido, ByteBuffer biblioteca de serialização base e capaz de versionamento. No entanto, é um pouco difícil de usar como você precisa comprimento gravação invólucro aulas sobre ele.

À luz das suas deficiências, eu recentemente fez uma Java somente biblioteca de serialização inspirado pela SBE e FIX-protocolo (protocolo comum mercado financeiro para mensagens comerciais de câmbio / quote), que tenta manter as vantagens de ambos ao mesmo tempo superar sua fraquezas. Você pode dar uma olhada em https://github.com/iceberglet/anymsg

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top