web-dev-qa-db-ja.com

Java Serialization?

私は現在、これらのオブジェクトを後で回復できるように、あらゆる種類のオブジェクト(その実装には制御がありません)を永続化する必要があるプロジェクトに取り組んでいます。

開発時にライブラリのユーザーを制限できないため、ORMを実装できません。

最初の選択肢は、Javaデフォルトのシリアル化でシリアル化することでしたが、ユーザーが同じオブジェクトの異なるバージョン(属性、タイプ、名前、 ...)。

XMLEncoderクラス(オブジェクトをXMLに変換する)を試しましたが、機能が不足していることがわかりました(たとえば、Enumをサポートしていません)。

最後に、JAXBも試しましたが、これはユーザーにクラスに注釈を付けることを強制します。

良い代替品はありますか?

46
Alotor

あなたにとって最も簡単なことは、シリアル化IMOを使用することですが、クラスのシリアル化された形式(とにかく実際に行うべきです)についてより多くの考えを入れてください。例えば:

  1. SerialUIDを明示的に定義します。
  2. 必要に応じて、独自のシリアル化されたフォームを定義します。

直列化された形式はクラスのAPIの一部であり、その設計には慎重な検討が必要です。

私が言ったことのほとんどすべてがEffective Javaから来ているので、私は多くの詳細には立ち入りません。代わりに、特にシリアル化に関する章を参照してください。実行中のすべての問題について警告し、問題の適切な解決策を提供します。

http://www.Amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/032135668


とは言っても、非シリアル化のアプローチをまだ検討している場合は、次のとおりです。

XMLマーシャリング

多くの人が指摘しているように、選択肢はありますが、下位互換性に関しては同じ問題に直面するでしょう。ただし、XMLマーシャリングを使用すると、初期化中に一部のフレームワークがいくつかのチェックを行う可能性があるため、これらをすぐにキャッチできます。

YAMLへ/からの変換

これは私がいじっていたアイデアですが、YAML形式(少なくともカスタムtoString()形式として)が本当に好きでした。しかし、実際には、唯一の違いは、XMLではなくYAMLにマーシャリングすることです。唯一の利点は、YAMLがXMLよりも人間が読みやすいことです。同じ制限が適用されます。

9
Jack Leow

2011年であり、商用グレードREST Webサービスプロジェクトでは、次のシリアライザーを使用して、クライアントにさまざまなメディアタイプを提供します。

  • XStream (JSONではなくXMLの場合)
  • Jackson (JSONの場合)
  • Kryo (高速でコンパクトなバイナリシリアル化形式)
  • Smile (Jackson 1.6以降に付属のバイナリ形式)。
  • Javaオブジェクトのシリアル化。

最近、他のシリアライザーを試しました:

  • SimpleXML は安定しているように見え、XStreamの2倍の速度で実行されますが、私たちの状況には少し多すぎる設定が必要です。
  • YamlBeans にはいくつかのバグがありました。
  • SnakeYAML には日付に関する小さなバグがありました。

Jackson JSON、Kryo、およびJackson Smileはすべて、古き良きJava Object Serialization、約3倍から4.5倍です。XStreamは遅い側です。ポイント。他の3つを監視し続けます。

39
Jim Ferrans

http://x-stream.github.io/ はいいですね、ご覧ください!とても便利

20
krosenvold

この実装には制御がありません

解決策はこれをしないでくださいです。型の実装を制御できない場合は、シリアル化しないでください。話の終わり。 Javaシリアル化は、型の異なるバージョン間のシリアル化の非互換性を管理するためのserialVersionUIDを提供します。実装を制御しない場合、開発者がクラスを変更したときにIDが正しく変更されていることを確認できません。

「ポイント」の簡単な例を見てみましょう。デカルト座標系または極座標系のいずれかで表すことができます。これらの種類の修正に動的に対処できるシステムを構築するのは非常にコストがかかります。実際には、シリアル化を設計するのはクラスの開発者でなければなりません。

要するに、間違っているのは設計であり、技術ではありません。

14
johnstok

googleはバイナリプロトコルを考案しました- http://code.google.com/apis/protocolbuffers/ はXMLに比べて高速で、ペイロードが小さくなっています。

プロトコルバッファの利点の1つは、C、C++、pythonおよびJavaと情報を交換できることです。

9
anjanb

また、非常に高速なJDKシリアル化ドロップイン置換: http://ruedigermoeller.github.io/fast-serialization/

5
R.Moeller

Gson でjsonにシリアライズしてみてください。

5
Benno Richters

シリアル化の速度が重要な場合は、JVMシリアライザーの包括的なベンチマークがここにあります。

3
Andrejs

個人的には、Smalltalk(VWとSqueakの両方)とPythonとの相互運用性を備えているため、 Fame をよく使用します。 (免責事項、私は名声プロジェクトの主な貢献者です。)

1
akuhn

Betwixt はオブジェクトをシリアル化するための優れたライブラリです-しかし、それは自動的なものではありません。シリアル化する必要のあるオブジェクトの数が比較的固定されている場合、これは良い選択肢かもしれませんが、「顧客」が常にあなたに新しいクラスをスローしようとしている場合、それは価値があるよりも多くの努力かもしれません(ただし、すべての特殊なケースでXMLEncoderよりも間違いなく簡単です)。

もう1つのアプローチは、顧客があなたに投げるオブジェクトに適切な.betwixtファイルを提供することを要求することです(これにより、それらに対する責任を効果的にオフロードします)。

ロングとショート-シリアル化はhardです-完全に脳死のアプローチはありません。 Javaシリアル化は私がこれまで見た限りの脳死の解決に近いが、あなたが見つけたように、バージョンuid値の誤った使用はそれを破ることができる。Javaシリアル化にはマーカー 'Serializable'インターフェースの使用も必要です。そのため、ソースを制御できない場合は、そのソースで運が悪くなります。

要件があなたが説明するように本当に難しい場合、オブジェクト/アスペクト/何でも何らかのBCE(バイトコード変更)に頼らなければならないかもしれません。これは、小規模な開発プロジェクトの領域を超えて、Hibernate、Casper、またはORMの領域に移行しています。

1
Kevin Day

おそらく Castor

1
toolkit

SBEは、高速のバイトバッファベースのシリアル化ライブラリ用に確立されたライブラリであり、バージョン管理が可能です。ただし、長さのラッパークラスを記述する必要があるため、使用するのは少し難しいです。

その欠点に照らして、私は最近、SBEとFIXプロトコル(トレード/クォートメッセージを交換する一般的な金融市場プロトコル)に触発されたJavaのみのシリアル化ライブラリを作成しました。 https://github.com/iceberglet/anymsg をご覧ください

0
Iceberglet

別のアイデア:キャッシュを使用します。キャッシュにより、アプリケーションの制御、スケーラビリティ、堅牢性が大幅に向上します。ただし、まだシリアル化する必要がありますが、キャッシングサービスフレームワーク内で管理がはるかに簡単になります。キャッシュは、メモリ、ディスク、データベース、アレイ、またはすべてのオプションに保持できます。一方をオーバーフロー、スタンバイ、他方をフェールオーバーします。 Commons JCSとEhcacheは2つのJava実装であり、後者は最大32 GBのストレージが無料のエンタープライズソリューションです(免責事項:ehcacheでは動作しません;-))。

0
Net Dawg