Java-Serialisierung - Vor- und Nachteile nutzen oder vermeiden? [geschlossen]

20

Die Serialisierung wird für die Persistenz in Java verwendet. Es kann in Ordnung sein, einige Objekte mithilfe der Serialisierung beizubehalten. Bei einer großen Anzahl von Objekten sind ORM, Datenbank usw. möglicherweise besser. Es scheint, dass die Serialisierung nur für kleine Aufträge nützlich ist. Vielleicht irre ich mich. Erzählen Sie mir bitte, welche Vorteile die Serialisierung gegenüber Nicht-Serialisierungsmethoden hat. Wann sollte es angewendet und wann vermieden werden?

Diese Frage kam mir in den Sinn, nachdem ich den DZone-Artikel Is Object Serialization Evil gesehen hatte.

Und dies sind die Zeilen, aus denen meine Frage hervorging:

Wenn Sie sich Java und seine Sitzungsobjekte ansehen, wird die reine Objektserialisierung verwendet. Unter der Annahme, dass eine Anwendungssitzung relativ kurzlebig ist, dh höchstens einige Stunden, ist die Objektserialisierung einfach, gut unterstützt und in das Java-Konzept einer Sitzung integriert. Wenn die Datenpersistenz jedoch über einen längeren Zeitraum, möglicherweise Tage oder Wochen, andauert und Sie sich über neue Versionen der Anwendung Gedanken machen müssen, wird die Serialisierung schnell schlecht. Wie jeder gute Java-Entwickler weiß, benötigen Sie eine echte Serialisierungs-ID (serialVersionUID) und nicht nur ein 1L, wenn Sie ein Objekt auch in einer Sitzung serialisieren möchten, und Sie müssen die Serializable-Schnittstelle implementieren. Die meisten Entwickler kennen jedoch die tatsächlichen Regeln für den Java-Deserialisierungsprozess nicht. Wenn sich Ihr Objekt geändert hat, können Sie dem Objekt nicht nur einfache Felder hinzufügen. Es ist möglich, dass Java das Objekt nicht korrekt deserialisieren kann, auch wenn sich die Serialisierungs-ID nicht geändert hat. Plötzlich können Sie Ihre Daten nicht mehr abrufen, was von Natur aus schlecht ist.

Mögen Entwickler, die dies lesen, vielleicht sagen, dass sie niemals Code schreiben würden, der dieses Problem hätte. Das mag stimmen, aber was ist mit einer Bibliothek, die Sie verwenden, oder einem anderen Entwickler, der nicht mehr in Ihrem Unternehmen beschäftigt ist? Können Sie garantieren, dass dieses Problem niemals auftreten wird? Die einzige Möglichkeit, dies zu gewährleisten, ist die Verwendung einer anderen Serialisierungsmethode.

Wolkenkratzer
quelle
Würde es Ihnen etwas ausmachen, etwas näher darauf einzugehen, was speziell in dem genannten Artikel Ihre Frage verursacht hat?
gnat
@gnat - fügte die Zeilen der Frage hinzu.
Wolkenkratzer
Der Teil über "nicht nur ein 1L" ist nicht korrekt.
user207421

Antworten:

15

Die Serialisierung wird hauptsächlich in zwei Bereichen verwendet:

  • Prototyping von Persistenz

    Nahezu jedes Objektdiagramm kann schnell serialisiert werden. Für schnelle Proof-of-Concepts oder Quick-and-Dirty-Anwendungen ist dies möglicherweise schneller als das Einrichten einer echten ORM-Ebene oder eines anderen Persistenzsystems

  • Kurzzeitspeicherung von nahezu beliebigen Objekten:

    Anwendungsserver tendieren beispielsweise dazu, Sitzungsinformationen mithilfe der Serialisierung beizubehalten. Dies hat den Vorteil, dass die Werte in der Sitzung nahezu beliebig sein können (solange sie serialisierbar sind).

Für fast alle anderen Anwendungen sind die Nachteile, die Sie (und der Artikel) erwähnen, zu groß: Das genaue Format ist schwer stabil zu halten, Klassenänderungen können Ihre serialisierten Daten leicht unleserlich machen, das Lesen / Schreiben der Daten in Nicht-Java-Code ist fast unmöglich unmöglich (oder zumindest viel schwieriger als nötig).

JAXB und ähnliche Technologien bieten ähnliche Funktionen zu ähnlich niedrigen Kosten und reduzieren gleichzeitig einige der Probleme.

Joachim Sauer
quelle
Ich würde JAXB nicht 'low cost' nennen - das Schema muss geschrieben werden.
Kevin Cline
3
@kevincline: Sie brauchen kein Schema mit JAXB, es ist völlig optional (und Sie können es sogar aus Ihren Klassen generieren, wenn Sie möchten). Außerdem: Wenn JAXB aus irgendeinem Grund nicht nützlich ist, gibt es viele Alternativen, wie z. B. XML-Beans, die genauso gut funktionieren.
Joachim Sauer
12

Ich verwende die Objektserialisierung, um bei unerwarteten Produktionsfehlern eine Post-Mortem-Analyse zu ermöglichen. Die Eingaben für eine Berechnung werden in eine Datendatei serialisiert. Wenn ein Fehler gemeldet wird, kann ein einfaches Programm die Eingaben neu laden und die Berechnung mit einem angehängten Debugger erneut ausführen. Oder es kann eine groovige Shell verwendet werden, um die Objekte neu zu laden und bei Bedarf zu ändern.

Wir verwenden die Serialisierung auch, um Java-Objekte über HTTP an einen Webdienst zu übergeben. Viel einfacher als das Serialisieren von und nach Text. Der Nachteil ist, dass die Client- und Server-Installationen zusammen bereitgestellt werden müssen, aber das ist kein Problem, da wir beide Seiten kontrollieren.

Kevin Cline
quelle
3
Das ist ein interessanter Anwendungsfall! Zu klein, um ein "komplexeres" System zu fordern, und die meisten Nachteile entfallen!
Joachim Sauer
Wir haben jetzt einen Post-Mortem-Analyzer geschrieben, der mithilfe von POI eine Tabelle aus den Java-Objekten erstellt, um die Anzeige zu vereinfachen. Dies hat uns viele Stunden der Prüfung der Protokolldatei erspart.
Kevin Cline
7

Was sind die Vorteile der Serialisierung gegenüber Nicht-Serialisierungsmethoden?

Die Java-Serialisierung hat einige Vorteile:

  • Integriert in das System : Sie müssen sich nicht auf Tools, Bibliotheken oder Konfigurationen von Drittanbietern verlassen.

  • Zumindest am Anfang relativ einfach zu verstehen .

  • Jeder Entwickler weiß es (oder sollte). Unabhängig davon, ob Java-Entwickler Java-Objekte genehmigen oder ablehnen, kennen sie sich wahrscheinlich mit der Serialisierung von Java-Objekten aus.

Und natürlich gibt es auch Nachteile:

  • Umgeht den Standard-Java-Flow. Weist Speicher zu, ruft jedoch keinen Konstruktor auf, sodass vorübergehende Felder nicht initialisiert werden. Felder werden in alphabetischer Reihenfolge und nicht in der Quellreihenfolge initialisiert.

  • Nicht so platzsparend, aber auch nicht schrecklich. Möglicherweise möchten Sie das Ergebnis komprimieren.

  • Spröde, es sei denn, Sie treffen Vorkehrungen, wenn sich Ihre Objekte ändern. Und selbst dann.

Wann sollte es angewendet und wann vermieden werden?

Verwenden Sie, wenn :

  • Bereitstellungsgröße ist wichtig. In das System eingebaut, also 0 zusätzliche Bytes.

  • Alle Schauspieler werden kompatible Versionen verwenden.

  • Langzeitlagerung ist kein Problem.

Vermeiden Sie wann :

  • Keine der oben genannten Aussagen trifft zu.
JvR
quelle
3

Serialisierung und eine ORM / Datenbank sind verschiedene Dinge, obwohl es einige Überschneidungen gibt.

Ein serialisiertes Objekt stellt alle Informationen dar, die zum "Auftauen" eines beständigen Objekts und zum erneuten Auffüllen seiner Daten erforderlich sind. Ein ORM und eine Datenbank speichern Daten in einer Datenbank. Eine Klasse kann Informationsfelder enthalten, die vom ORM nicht in der Datenbank gespeichert werden, z. B. berechnete Felder.

Darüber hinaus lösen die Serialisierung und ein ORM verschiedene Probleme. Die Serialisierung löst das Problem, ein Objektdiagramm in einem Stream (Speicher, Dateisystem usw.) zu speichern. Ein ORM übernimmt die Zuordnung von Informationen zu Datenbankspalten und das Abrufen und Instanziieren von Objekten. Außerdem werden Feinheiten wie das Suchen und das verzögerte Laden bereitgestellt.

Verwenden Sie ein ORM, wenn Sie Daten in einer Datenbank beibehalten möchten, wenn Sie mit großen Datenmengen zu tun haben oder wenn Sie Berichte, Suchen / Abfragen, Warehousing oder andere Dinge benötigen, in denen Datenbanken gut sind. Verwenden Sie die Serialisierung, wenn Sie eine Darstellung Ihrer Datenstruktur (en) auf Disc speichern möchten.

Sam
quelle
0

Serialisierung wird in der Praxis selten eingesetzt.

Wie bereits erwähnt, besteht der häufigste Anwendungsfall für die Serialisierung darin, Objekte als Blobs in einer Sitzungsdatenbank zu speichern. Dies funktioniert aus zwei Gründen gut: Sitzungen sind in der Regel kurzlebig und die Sitzungsdatenbank enthält keine Kenntnisse darüber, wie beliebige Objekte einem relationalen Modell zugeordnet werden können.

Für Daten, die über einen längeren Zeitraum aufbewahrt werden müssen (wie bei einem Amazon-Einkaufswagen), empfiehlt es sich, diese Daten in einer Datenbank zu speichern.

Der Sitzungspersistenzmechanismus stellt sicher, dass ein Benutzer mit einer aktiven Sitzung an denselben Server zurückgegeben wird. Auf die Sitzungsdatenbank wird nur zugegriffen, wenn ein Server ausfällt und der Benutzer auf einen neuen Server umgeleitet wird. Der neue Server erkennt eine aktive Sitzung, findet sie jedoch nicht im Arbeitsspeicher. Daher wird versucht, sie aus der Sitzungsdatenbank abzurufen, um dem Benutzer eine nahtlose Benutzererfahrung zu bieten.

Bei diesem Ansatz gibt es zwei Probleme:

Erstens ist das Leeren von Sitzungsdaten in die Sitzungsdatenbank ein langsamer Prozess. Das zu häufige Leeren von Sitzungsdaten beeinträchtigt die Leistung, und die meisten Server sind so konfiguriert, dass alle 30 Sekunden, jede Minute oder länger geleert wird. Diese "scheinbare" Failover-Lösung ist niemals 100% effektiv.

Zweitens stimmen die meisten Kunden meiner Erfahrung nach darin überein, dass eine Fehlermeldung ausgegeben wird, in der der Benutzer aufgefordert wird, sich anzumelden und es in den seltenen Fällen, in denen ein Server ausfällt, erneut zu versuchen. In diesem Fall schalten wir die Sitzungsdatenbank vollständig aus und genießen die Leistungssteigerung.

Eine andere Verwendung der Serialisierung besteht darin, schnellere Antwortzeiten bereitzustellen, indem Frameworks wie Flex verwendet werden, die die Serialisierung und Komprimierung von Objektdiagrammen für Server-Client-Interaktionen verwenden.

Wie bereits erwähnt, gibt es einige kreative und nützliche Gründe für die Verwendung der Serialisierung, die in der Praxis jedoch selten sind.

Historisch gesehen ist es schwierig, die Serialisierung korrekt und zuverlässig zu implementieren, was die Verwendung auf eine kleine Anzahl von Fällen beschränkt. Die meisten Entwickler werden Objekte niemals selbst serialisieren, sondern verlassen sich möglicherweise auf Frameworks, die dies hinter den Kulissen tun.

Eric w
quelle
2
"Serialisierung wird in der Praxis selten eingesetzt." - Serialisierung wird in der Welt der REST-Webdienste häufig als " Serialisierung" bezeichnet . Die meiste Zeit beschäftigt man sich nur mit Strings und Integers oder ähnlichem - aber es ist eine reale Sache und komplexere Objekte müssen sich dessen bewusst sein. Zu sagen, dass es selten verwendet wird, ignoriert eine große Anzahl von Domänen, die es häufig verwenden.
0

Kurze Antwort auf "Wann sollte Java-Serialisierung verwendet werden?" Und "Wann sollte Java-Serialisierung vermieden werden?"

Verwenden Sie Java-Serialisierung, wenn

  • Es sollte nur wenig Codierung erforderlich sein
  • Es spielt keine Rolle, dass binäre Daten nicht für Menschen lesbar sind
  • Suche in serialisierten Daten ist nicht erforderlich (datenbankähnliche Abfrage nicht möglich)
  • entweder
    • serialisierte Datenstruktur ändert sich nicht oder
    • es spielt keine rolle, ob gespeicherte serialisierte daten nach "datenstrukturänderung" nicht mehr lesbar sind (dh sitzungsdaten in einer web-app)

In allen anderen Situationen ist "Binary Java Serialization" schlecht

Alternativen

  • XML-Serialisierung
  • NOSQL-Datenbank
  • relationale Datenbank mit ORM
k3b
quelle