Какая альтернатива сериализации Java является лучшей?

StackOverflow https://stackoverflow.com/questions/239280

Вопрос

В настоящее время я работаю над проектом, в котором необходимо сохранять объекты любого типа (реализацию которого мы не можем контролировать), чтобы эти объекты можно было впоследствии восстановить.

Мы не можем реализовать ORM, потому что не можем ограничить пользователей нашей библиотеки во время разработки.

Нашей первой альтернативой была сериализация с помощью сериализации Java по умолчанию, но у нас возникло много проблем с восстановлением объектов, когда пользователи начали передавать разные версии одного и того же объекта (атрибуты изменили типы, имена и т. д.).

Мы попробовали использовать класс XMLEncoder (преобразует объект в XML), но обнаружили недостаток функциональности (например, он не поддерживает Enums).

Наконец, мы также попробовали JAXB, но это заставляет наших пользователей аннотировать свои классы.

Есть хорошая альтернатива?

Это было полезно?

Решение

Вам проще всего по-прежнему использовать сериализацию, IMO, но уделить больше внимания сериализованной форме классов (что вам действительно следует делать в любом случае). Например:

<Ол>
  • Явно определите SerialUID.
  • Определите свою собственную сериализованную форму, где это необходимо.
  • Сериализованная форма является частью API класса, и ее дизайн должен быть тщательно продуман.

    Я не буду вдаваться в подробности, так как почти все, что я сказал, происходит из Effective Java. Вместо этого я отсылаю вас к нему, в частности к главам о сериализации. Он предупреждает вас обо всех проблемах, с которыми вы сталкиваетесь, и предоставляет правильные решения проблемы:

    http://www.amazon.com/Effective-Java-2nd-Joshua- Блох / др / 0321356683 <Ч>

    С учетом сказанного, если вы все еще рассматриваете подход без сериализации, вот пара:

    XML-сортировка

    Как уже указывалось многими, это вариант, но я думаю, что вы все равно столкнетесь с теми же проблемами с обратной совместимостью. Однако, с помощью XML-маршалинга, мы надеемся, вы сразу же поймете это, поскольку некоторые фреймворки могут выполнять некоторые проверки для вас во время инициализации.

    Преобразование в / из YAML

    Это идея, с которой я играю, но мне очень понравился формат YAML (по крайней мере, как собственный формат toString ()). Но на самом деле единственное отличие для вас состоит в том, что вы будете использовать YAML вместо XML. Единственное преимущество заключается в том, что YAML немного более удобочитаем, чем XML. Применяются те же ограничения.

    Другие советы

    На дворе 2011 год, и в проекте веб-сервисов REST коммерческого уровня мы используем следующие сериализаторы, чтобы предлагать клиентам различные типы мультимедиа:

    • XStream (для XML, но не для JSON)
    • Джексон (для JSON)
    • Крио (быстрый и компактный формат двоичной сериализации)
    • Улыбка (двоичный формат, который поставляется с Jackson 1.6 и более поздними версиями).
    • Сериализация объектов Java.

    Недавно мы экспериментировали с другими сериализаторами:

    • ПростоXML кажется надежным, работает в 2 раза быстрее, чем XStream, но требует слишком сложной настройки для нашей ситуации.
    • YamlBeans было пару ошибок.
    • ЗмеяYAML была небольшая ошибка, связанная с датами.

    Jackson JSON, Kryo и Jackson Smile были значительно быстрее, чем старая добрая сериализация объектов Java, примерно в 3–4,5 раза.XStream работает медленно.Но на данный момент это все надежные варианты.Мы продолжим следить за остальными тремя.

    http://x-stream.github.io/ приятно, пожалуйста, посмотри на это! Очень удобно

      

    какой реализации мы не имеем никакого контроля

    Решением является не делайте этого . Если у вас нет контроля над реализацией типа, вам не следует его сериализовывать. Конец истории. Сериализация Java предоставляет serialVersionUID специально для управления несовместимостью сериализации между различными версиями типа. Если вы не контролируете реализацию, вы не можете быть уверены, что идентификаторы меняются правильно, когда разработчик меняет класс.

    Возьмите простой пример «Точки». Он может быть представлен либо декартовой, либо полярной системой координат. Вам было бы непозволительно дорого создать систему, которая могла бы динамически справляться с такого рода исправлениями - это действительно должен быть разработчик класса, который разрабатывает сериализацию.

    Короче говоря, это ваш дизайн, а не технология.

    Google разработал двоичный протокол - http://code.google.com/apis/ protocolbuffers / быстрее, имеет меньшую полезную нагрузку по сравнению с XML - что другие предложили в качестве альтернативы.

    Одним из преимуществ буферов протокола является то, что он может обмениваться информацией с C, C ++, Python и Java.

    Попробуйте сериализовать в json, например, с помощью Gson .

    Также очень быстрая замена вставки сериализации JDK: http://ruedigermoeller.github.io/fast-serialization/

    Если для вас важна скорость сериализации, то здесь есть комплексный тест сериализаторов JVM:

    Лично я часто использую Fame , поскольку он обеспечивает совместимость с Smalltalk (как VW, так и VW). Писк) и питон. (Отказ от ответственности, я основной вкладчик проекта Fame.)

    Возможно, Castor ?

    Betwixt - хорошая библиотека для сериализации объектов, но она не будет автоматическим видом вещи. Если количество объектов, которые вы должны сериализовать, относительно фиксировано, это может быть хорошим вариантом для вас, но если ваш «клиент» будет все время бросать вам новые классы, это может потребовать больше усилий, чем стоит ( Определенно проще, чем XMLEncoder для всех особых случаев, хотя).

    Другой подход заключается в том, чтобы потребовать от вашего клиента предоставления соответствующих файлов .betwixt для любых объектов, которые они вам бросают (это эффективно снимает с них ответственность).

    Длинная и короткая - сериализация сложная - нет абсолютно мертвого подхода к этому. Сериализация Java так же близка к мертвому решению, как я когда-либо видел, но, как вы обнаружили, неправильное использование значения версии uid может сломать его. Сериализация Java также требует использования интерфейса маркера «Serializable», поэтому, если вы не можете контролировать свой источник, вам не повезло с этим.

    Если требование действительно столь же сложно, как вы описываете, вам, возможно, придется прибегнуть к некоторому BCE (модификации байт-кода) для объектов / аспектов / чего угодно. Это выходит за рамки небольшого проекта разработки и попадает в сферу Hibernate, Casper или ORM ....

    Еще одна идея: использовать кеш. Кэши обеспечивают лучшее управление, масштабируемость и надежность приложения. Хотя все еще нужно сериализоваться, но управление становится намного проще с помощью инфраструктуры кэширования. Кэш-память может сохраняться в памяти, на диске, в базе данных или массиве - или во всех параметрах, при этом один из них является переполнением, резервированием, переключением при сбое для другого. Commons JCS и Ehcache - две реализации Java, последняя - корпоративное решение, свободное до 32 ГБ памяти (отказ от ответственности: я не работаю для ehcache ;-)).

    SBE - признанная библиотека для быстрой библиотеки сериализации на основе байтовых буферов, способная к управлению версиями. Однако его немного сложно использовать, так как над ним нужно писать классы-обёртки длины.

    В свете его недостатков я недавно создал библиотеку сериализации только для Java, основанную на SBE и FIX-протоколе (общий протокол финансового рынка для обмена сообщениями о сделках / котировках), который пытается сохранить преимущества обоих, преодолевая их недостатки. Вы можете взглянуть на https://github.com/iceberglet/anymsg

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top