PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java Objekt-Serialisierung


DocEW
2007-06-22, 10:55:28
Hallo!

Ist es irgendwie möglich, den Zustand eines Objektes auf Festplatte zu speichern und wieder zu laden, wenn dieses nicht das Serializable Interface implementiert?
Ich habe dieses Objekt in einem bestimmten "nicht so schnell wieder erreichbaren" Zustand und will den Computer ausschalten können bzw. nach einem Absturz von der Stelle weitermachen können.

Danke für Tipps & vG,

DocEW

Shink
2007-06-22, 11:08:47
Nun ja: Nein, nicht wirklich. Wenn du Referenzen auf andere Objekte drin hast, die sich wirklich nicht serialisieren lassen (z.B. einen Socket, der gerade eine bestimmte Verbindung hält), wie soll das dann gehen?
Wenn du nur serializable Members hast, ginge es natürlich, aber warum soll dann nicht gleich das Objekt selbst serializable sein?

Vielleicht musst du uns aber auch einfach mehr über das Problem sagen.

DocEW
2007-06-22, 16:17:27
Hi!
Danke für Deine Antwort.
Also, ich denke schon, dass sich dieses Objekt serialisieren liesse. Dummerweise habe ich keinen source-code davon, kann also auch nix selbst rumbasteln. Ich wäre also wohl auf eine komplett andere Lösung angewiesen... beispielsweise, das komplette Speicherabbild irgendwie zu schreiben/lesen oder sowas... Hm. :-/

Gnafoo
2007-06-22, 16:39:32
Oder du musst versuchen dir alles zu merken, was für die Rekonstruktion nötig ist und dann manuell ein Objekt instanziieren, die Eigenschaften setzen etc. pp. Ob das funktionieren kann hängt natürlich vom konkreten Fall ab.
Speicher auslesen o. ä. wird vermutlich in den seltensten Fällen funktionieren, denn meistens hat man ja auch Referenzen etc., die bei jeder Ausführung anders aussehen dürften.

Shink
2007-06-22, 17:33:21
Ja, das dürfte ganz brauchbar funktionieren: Z.B. einen Decorator, der sich von dieser Klasse ableitet und bei jedem Methodenaufruf diesen mitprotokolliert.
Wenn du nur serializable Objekte in die Klasse reinsteckst, ginge das sogar ganz einfach und allgemein wiederverwendbar.

DocEW
2007-06-22, 21:44:04
Ich habe leider keine Ahnung, was dieses Objekt intern so alles anstellt... damit beantwortet sich die Frage ja irgendwie auch schon von selbst - ich weiß ja noch nichtmal, was ich überhaupt alles speichern müsste.

Vielleicht noch ein letzter Versuch (vielleicht ist ja noch jemand kreativ): Das Problem ist, dass der Konstruktor der Klasse eine Netzwerkverbindung benötigt. Das ist nur leider sehr blöde, wenn ich mal unterwegs bin und trotzdem arbeiten will.

Gnafoo
2007-06-22, 22:32:23
Vielleicht kannst du die Netzwerkseite mit vertretbarem Aufwand über einen eigenen selbst programmierten Proxy emulieren? X-D

Gast
2007-06-24, 14:59:12
Vielleicht kannst du die Netzwerkseite mit vertretbarem Aufwand über einen eigenen selbst programmierten Proxy emulieren? X-D
Das hieße dann leider, einen Lizensierungs-Server selbst zu schreiben! X-D

DocEW
2007-06-24, 14:59:49
Das hieße dann leider, einen Lizensierungs-Server selbst zu schreiben! X-D
login vergessen...

del_4901
2007-06-30, 21:21:20
Du kannt eine Referenz transient machen. Dann wird Sie bei der Serializierung nicht beachtet und bekommt einen null-Pointer. Vllt. hilft dir das ja weiter. Dann kannst du zwar nicht dieses Objekt sichern, aber wenigstens den restlichen Objektbaum.

DocEW
2007-07-09, 11:33:31
Du kannt eine Referenz transient machen. Dann wird Sie bei der Serializierung nicht beachtet und bekommt einen null-Pointer. Vllt. hilft dir das ja weiter. Dann kannst du zwar nicht dieses Objekt sichern, aber wenigstens den restlichen Objektbaum.
Aber dafür müsste ich ja den Source-code der Klasse haben, oder? Wie soll ich "nachträglich" eine Referenz transient machen?

Shink
2007-07-09, 11:41:56
Du müsstest wohl alles in eine Datei mitloggen, was du machst, um zum Objekt zu kommen und was du damit machst (Methodenaufrufe, serialisierte Übergabeparameter oder wenn sie nicht serialisierbar sind: Informationen darüber, wie man sie realisieren kann) und beim Neustart mit Method.invoke() -Aufrufen wieder das alte Objekt zusammenzubasteln.

Einfach und mit wenig Aufwand geht da wohl nix; wenn du wirklich was los hast kannst du das sogar automagisch über Decorators realisieren (wobei ich ehrlich gesagt nicht das Gefühl hab, dass du dem schon gewachsen bist).
Vielleicht solltest du dein Problem ändern wenn du keine Lösung dafür hast... hast du wirklich keine Alternative?

DocEW
2007-07-10, 11:15:53
Anscheinend habe ich das Problem nicht gut genug erklärt oder verstehe deinen Lösungsvorschlag nicht.
Du müsstest wohl alles in eine Datei mitloggen, was du machst, um zum Objekt zu kommen ... und beim Neustart mit Method.invoke() -Aufrufen wieder das alte Objekt zusammenzubasteln.
Wie gesagt benötigt der Konstruktor des Objekts bereits eine Netzwerkverbindung. Wie soll ich dieses Objekt überhaupt erzeugen? Großartig mitloggen brauche ich nichts - ist ein Einzeiler:
ProblemObjekt po = new ProblemObjekt() :)

Einfach und mit wenig Aufwand geht da wohl nix; wenn du wirklich was los hast kannst du das sogar automagisch über Decorators realisieren (wobei ich ehrlich gesagt nicht das Gefühl hab, dass du dem schon gewachsen bist).
Schade dass ich hier so einen hilflosen Eindruck mache! ;)
Na, also ein Design Pattern kann ich schon anwenden. Also mache ich einen ProblemObjektDekorierer, der eine Unterklasse ist - gut. Und dann? Der kann natürlich sogar serialisierbar sein, hilft nur nix, weil die ganzen geerbten Attribute nicht serialisiert werden. Da gibt es zum Beispiel eine eigene Implementation einer LinkedList mit innerer Klasse Link. Müsste ich dann versuchen, für diese ganzen Klassen auch Dekorators erstellen?

Vielleicht solltest du dein Problem ändern wenn du keine Lösung dafür hast... hast du wirklich keine Alternative?
Ich weiß nicht, wie ich oben beschriebene Code-Zeile umgehen soll, bzw. wie ich die gleiche Wirkung ohne einen Konstruktoraufruf hinbekommen soll.

del_4901
2007-07-10, 13:54:07
Aber dafür müsste ich ja den Source-code der Klasse haben, oder? Wie soll ich "nachträglich" eine Referenz transient machen?

Den Code den du verwendest und selber nicht besitzt sollst du transient machen. Wenn du das danach seriallisiert hast, musst du diese Referenzen wieder neu aufsetzen.

Shink
2007-07-10, 14:51:47
Anscheinend habe ich das Problem nicht gut genug erklärt oder verstehe deinen Lösungsvorschlag nicht.

Wie gesagt benötigt der Konstruktor des Objekts bereits eine Netzwerkverbindung. Wie soll ich dieses Objekt überhaupt erzeugen? Großartig mitloggen brauche ich nichts - ist ein Einzeiler:
ProblemObjekt po = new ProblemObjekt() :)

Gut, im Log stünde dann z.B., wenn ausgeführt:

Socket bla=new Socket(...);
ProblemObjekt po=new ProblemObjekt(bla);

Der "Log-Abarbeiterer" sollte dann Dinge tun wie:
- Mit Class.forName(String) die Klassen der Zwischenobjekte herauslesen
- Bei Konstruktoren mit Class.forName(String).getConstructor(Class[] der herausgelesenen Klassen).execute(Object[] der bisher herausgelesenen und instanzierten Zwischenobjekte) aufrufen.
- Bei Methodenaufrufen auf die so per Konstruktor erzeugten Zwischenobjekte mit getClass().getMethod(String name, Class[] Zwischenobjektklassen).execute(Object Objekt auf dem die Methode aufgerufen wird, Object[] Zwischenobjekte); die Methoden aufrufen.

Der Dekorator überschreibt dann "einfach" die Methoden der Problemklasse und ruft in allen zuerst die Logmeldung auf und dann die Methode der Basisklasse, ist dann aber wohl die einfachste Übung.

Klar trau ich dir was zu, aber ich hab nicht das Gefühl dass das die Lösung ist, die du hören willst.