Serializable - Bei Update ältere Daten importieren

Mujahiddin

Top Contributor
Einen guten Tag!
Um nicht abstrakt zu reden, komme ich gleich zur Sache:
Ich programmiere ein 'Vokabelheft', man kann Einträge einfügen, und diese dann speichern über Serializable..
Problem: Wenn ich eine Änderung am Code vornehme, sprich: Ich mach ein Update auf dieses Vokabelheft, müsste man alle Einträge vom alten Vokabelheft per Hand übernehmen, und das will ich vermeiden.
Galileo Computing hat auch nur eine Lösung per XML, aber da treten Fehler auf:

java.lang.InstantiationException: sun.awt.shell.Win32ShellFolder2
Continuing ...
java.lang.Exception: XMLEncoder: discarding statement XMLEncoder.writeObject(Win32ShellFolder2);
Continuing ...

Der Befehl wird zwar ausgeführt, die Datei ist danach aber leer.

Weiß wer weiter? ...
 
Ich denke mal, Du willst in einen Non-System Folder schreiben, sprich "My Computer", "Desktop" etc. Da gibt es allerdings bei einigen Java-Versionen einen Bug, der diesen Fehler erzeugt. Gibt doch mal einen echten Pfad an, absolut oder relativ.
 
So gesehen gibt er ja einen absoluten Pfad an... Den Pfad nimmt er nämlich über JFileChooser.getCurrentDirectory();, welchen man über selbigen auswählt.
Ich bin dort mit 'Aufwärts' auf den Desktop gegangen und hab in einen Unterordner gespeichert. Lags daran? Wie soll ich das über ein Filechooser denn verhindern?
 
worum gehts überhaupt, um 'Galileo Computing hat [..] eine Lösung per XML'?
wie soll man dazu etwas sagen, poste doch einen Link zum entsprechenden Kapitel,
sowie ein kleines Testprogramm, ohne FileChooser oder GUI, nur mit main-Methode, vorgegebenen Pfad und paar Dummy-Daten zu speichern
 
ich hab das auch mal mit dem XMLEn/Decoder ausprobiert und bin auf selbigen Fehler gestossen. Ich weiß nurnoch, dass das für mich damals absolut nicht nachvollziehbar war. Könnte dir jetzt nur eine normale Serialisierung mit dem ObjectOutputStream vorschlagen. Nachteile liegen denke auf der Hand, z.b. Dateien sind nicht im Editor lesbar bzw änderbar (könnte natürlich auch als Vorteil interpretiert werden 😉)

Nebenbei dann die Frage, die ich damals schon stellen wollte:
Was ist daran falsch?
Java:
import java.beans.*;
import java.io.*;

public class Test implements Serializable{
	private static final long serialVersionUID = 1L;
	private String s;
	private int i;
	public Test (String s, int i) {
		this.s = s;
		this.i = i;
	}
	public static void main(String[] args) throws FileNotFoundException {
		XMLEncoder xem = new XMLEncoder( new BufferedOutputStream( new FileOutputStream("test.xml")));
		XMLDecoder xde = new XMLDecoder( new BufferedInputStream( new FileInputStream("test.xml")));
		xem.writeObject(new Test("Hallo", 123));
		xem.close();
		Test test = (Test)xde.readObject();
		xde.close();
		System.out.println(test);
	}
	@Override
	public String toString() {
		return s + " " + i;
	}
}

Ergebnis:
Code:
java.lang.InstantiationException: Test
Continuing ...
java.lang.Exception: XMLEncoder: discarding statement XMLEncoder.writeObject(Test);
Continuing ...
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
	at com.sun.beans.ObjectHandler.dequeueResult(Unknown Source)
	at java.beans.XMLDecoder.readObject(Unknown Source)
	at Test.main(Test.java:17)

edit: also die AIOOBE erklär ich mir, weil die Datei einfach leer ist. Mir gehts eher um die Serialisierung. Warum macht er einfach garnix? 🙁
 
ahja stimmt, man braucht den Stdkonstruktor explizit... aber naja dann serialisier ich null. ich will aber schon die Attribute s und i von meinem Objekt serialisieren. (soweit war ich glaub dann damals auch 🙂)
 
man beachte das magisch 'und' in der Antwort von fastjack 😉
 
Zuletzt bearbeitet von einem Moderator:
Bei mir sieht das so aus:

Java:
static class Vokabelheft
	{
		public static Baum binaerbaum;
		public static void main(String[] args)
		{
			binaerbaum = new Baum();
			binaerbaum.add(new Entry("Kamikaze"));
			binaerbaum.add(new Entry("Fliege"));
			binaerbaum.add(new Entry("Test"));
			binaerbaum.add(new Entry("Katze"));
			binaerbaum.add(new Entry("Hund"));
			binaerbaum.add(new Entry("Roflz0r"));
			File file = new File("C:/TEST.xml");
			XMLEncoder enc = null;
			OutputStream fos = null;
			try
			{
				fos = new FileOutputStream(file);
				enc = new XMLEncoder(fos);
				enc.writeObject(binaerbaum);
				enc.close();
			}
			catch(IOException e)
			{
				e.printStackTrace();
			}
		}
	}
wenn ich jetzt TEST.xml öffne, finde ich nur ein <Baum> als object, keine unterobjekte (entry / Knoten etc)
ansonsten, per FileChooser etc. kommt wie üblich der oben genannte Fehler...

P.S. hier der Galileo Computing Link:

Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 14.12 Persistente Objekte und Serialisierung


// was sind beanskonforme Getter / Setter Methoden?
Und wie soll ich parameterlose Konstruktoren machen? Du meinst damit ohne 'public', oder? Aber dann könnte ich von außen nicht mehr drauf zugreifen!
 
parameterlos heißt ohne Parameter, nicht ohne Sichtbarkeits-Modifer

und ne intern versteckte Liste mit mehreren Unterelementen wird schwer, das entspricht ja auch nicht den 'beanskonforme Getter / Setter Methoden', wie du selber schon zitierst, diese beiden Punkte müssen erfüllt sein,
evtl. gehts, wenn eine normale ArrayList als ein Attribut gehalten wird, die ArrayList lässt sich ja zumindest serialisieren (dank manueller Unterstützungsmethoden), dann unterstützt es vielleicht auch XML
 
Also sprich: Die einzige Methode, einen solchen Baum XML-serialisierbar zu machen, ist, dass ich alle Unterelemente praktisch als Strings oder sonstiges abspeicher?
 
nicht einzig, aber ja, das wäre ein guter einfacher Weg,
neben String & Co. (edit: und anderen eigenen Objekten die ähnlich einfach aufgebaut sind )
evtl. auch ArrayList, denn die ist ja auch serialisierbar,

oder als Alternative:
du verwendest die Hilfsmethoden wie es ArrayList selber auch macht:

Java:
    /**
     * Save the state of the <tt>ArrayList</tt> instance to a stream (that
     * is, serialize it).
     *
     * @serialData The length of the array backing the <tt>ArrayList</tt>
     *             instance is emitted (int), followed by all of its elements
     *             (each an <tt>Object</tt>) in the proper order.
     */
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
	// Write out element count, and any hidden stuff
	int expectedModCount = modCount;
	s.defaultWriteObject();

        // Write out array length
        s.writeInt(elementData.length);

	// Write out all elements in the proper order.
	for (int i=0; i<size; i++)
            s.writeObject(elementData[i]);

	if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }

    }

    /**
     * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
     * deserialize it).
     */
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
	// Read in size, and any hidden stuff
	s.defaultReadObject();

        // Read in array length and allocate array
        int arrayLength = s.readInt();
        Object[] a = elementData = new Object[arrayLength];

	// Read in all elements in the proper order.
	for (int i=0; i<size; i++)
            a[i] = s.readObject();
    }
damit verläßt man den automatischen Bean-Standard zumindest teilweise
und kann durch manuellen Code die Serialisierung etwas genauer steuern


-----

ob das bei XML auch reicht, vermute ich wie gesagt die ganze Zeit nur, nicht getestet,
einfach mal eine ArrayList nach XML schicken, aber kann ich auch selber machen:
Java:
        XMLEncoder xem = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("test.xml")));
        ArrayList a = new ArrayList();
        a.add("test");
        a.add(Boolean.TRUE);
        xem.writeObject(a);
        xem.close();
->
Code:
<?xml version="1.0" encoding="UTF-8"?> 
<java version="1.6.0_13" class="java.beans.XMLDecoder"> 
 <object class="java.util.ArrayList"> 
  <void method="add"> 
   <string>test</string> 
  </void> 
  <void method="add"> 
   <boolean>true</boolean> 
  </void> 
 </object> 
</java>
hmm, wo das wohl herkommt?
 
Zuletzt bearbeitet von einem Moderator:

Zurück
Oben