ObjectInputStream

Hallo, ich habe mal ne Frage. Das Speichern funktioniert einwandfrei.

ich habe 1 Playlist klasse indem verschiedene Playlisten sind. Diese will ich bei Klick auf Laden
wieder aufrufen.
Geht das?

Fehlermeldung: Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.util.ArrayList cannot be cast to Data.Playlist

Java:
public void speichern(){

   
     try{
       FileOutputStream fileStream = new FileOutputStream("Playlisten.ser");
       ObjectOutputStream os= new ObjectOutputStream(fileStream);

            os.writeObject(playlist.getPanel1List());
            os.writeObject(playlist.getPanel2List());
            os.writeObject(playlist.getPanel3List());
            os.writeObject(playlist.getPanel4List());
            os.writeObject(playlist.getPanel5List());
            os.writeObject(playlist.getPanel6List());
            os.writeObject(playlist.getPanel7List());
            os.writeObject(playlist.getPanel8List());
            os.writeObject(playlist.getPanel9List());
            
            
       os.close();
   } catch (IOException ex){
       System.out.println("Schreibfehler: Playlisten.ser");
       ex.printStackTrace();
   }

 }
    
    public void laden() throws ClassNotFoundException{
        try{
            FileInputStream fileStream = new FileInputStream("Playlisten.ser");
            ObjectInputStream os = new ObjectInputStream(fileStream);
            
            //Objekte einlesen
            Object eins = os.readObject();
            
            
            //Objekte casten
            Playlist playlist = (Playlist)eins;
            
            
            os.close();
        }catch(IOException ex){
            System.out.println("Ladefehler: Playlisten.ser");
            ex.printStackTrace();
        }
    }
 
S

SlaterB

Gast
als erstes Objekt in der Datei steht anscheinend playlist.getPanel1List(),
woher soll man wissen welchen Typ das Objekt hat, welches da zurückgegeben wird, das könntest du doch sagen?
ist es eine ArrayList?
wieso willst du dann was anderes als eine ArrayList herauslesen?

edit:
> ich habe 1 Playlist klasse indem verschiedene Playlisten sind.
ok..
wirklich? zeige bitte bisschen Code von der Methode getPanel1List()

kann der Dateiinhalt auch nicht von einer früheren anderen Speicherung abstammen?


----------

in der Tat steckt aber auch ein sinnvoller Gedanke hinter all dem, der zu einem meiner Standard-Tipps hier im Forum führt:
speichere im ObjectOutputStream nur und genau EIN Objekt, speichere die playlist, fertig,
mit all ihren Unterobjekten abgelegt,

dann kannst du genau diese Playlist wieder auslesen, Unterobjekte holen wenn nötig
 
Zuletzt bearbeitet von einem Moderator:
getPanellist1 ist ein ArrayList<Track>

meine Playlistklasse

Java:
public Playlist() {
        panel1List = new ArrayList<Track>();
        panel2List = new ArrayList<Track>();
        panel3List = new ArrayList<Track>();
        panel4List = new ArrayList<Track>();
        panel5List = new ArrayList<Track>();
        panel6List = new ArrayList<Track>();
        panel7List = new ArrayList<Track>();
        panel8List = new ArrayList<Track>();
        panel9List = new ArrayList<Track>();
        playlistTrack = new ArrayList<String>();
    }

    public void addTrack(Track track, int a, int b) throws CannotReadException, TagException, ReadOnlyFileException, InvalidAudioFrameException, IOException {
        System.out.println("Playlist addTrack()");
        actTrack = track;
        int laengeArray = 0;

        //Panel 1
        if (a == 0 && b == 0) {
            System.out.println("Playlist Panel 1 hinzugefügt");
            getPanel1List().add(actTrack);
            laengeArray = getPanel1List().size();
            System.out.println("Playlist 1 Größe: " + laengeArray);

        }

        //Panel 2
        if (a == 1 && b == 0) {
            System.out.println("Playlist Panel 2 hinzugefügt");
            getPanel2List().add(actTrack);
            laengeArray = getPanel2List().size();
        }
}

    public ArrayList<Track> getPanel1List() {
        return panel1List;
    }

    /**
     * @return the panel2List
     */
    public ArrayList<Track> getPanel2List() {
        return panel2List;
    }

Habe mein Code etwas geändert

Java:
public void laden() throws ClassNotFoundException{
        try{
            FileInputStream fileStream = new FileInputStream("Playlisten.ser");
            ObjectInputStream os = new ObjectInputStream(fileStream);
           
            //Objekte einlesen
            Araylist<Track> eins = (Araylist<Track>) os.readObject();
            Araylist<Track> zwei = (Araylist<Track>) os.readObject();            
            
            os.close();
        }catch(IOException ex){
            System.out.println("Ladefehler: Playlisten.ser");
            ex.printStackTrace();
        }
    }

Fehler: Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.util.ArrayList cannot be cast to BuisnessLogik.Araylist
 
S

SlaterB

Gast
> BuisnessLogik.Araylist

BuisnessLogik.Arraylist wohl, noch eher hoffentlich BusinessLogik.Arraylist

und fällt dir dazu was ein? hast du ein package BusinessLogik (packages übrigens besser immer mit Kleinbuchstaben beginnen),
hast du eine eigene Klasse ArrayList darin?
das ist ganz böse da es eben java.util.ArrayList als zentrale API-Klasse gibt, da musst du mit den imports aufpassen
bzw. generell deine eigene ArrayList schnellstens löschen/ umbenennen

edit:
> Araylist<Track> eins = (Araylist<Track>) os.readObject();
ach, die Falschschreibweise ist dann ja doch richtig,
also es sind erwiesenermaßen ArrayLists in der Datei,
vorher wolltest du sie auf PlayList casten, das ging nicht, nun ArayList, geht auch nicht,
erkennst du ein Muster?
eine ArrayList kann nur eine ArrayList sein, eigentlich einfach
 
Zuletzt bearbeitet von einem Moderator:
ok, hab in der businessLogik die Klasse MP3Player und Verwaltung

Die ArrayList klasse hat er eigenständig erstellt

wegen dieser Zeile

Java:
Araylist<Track> eins = (Araylist<Track>) os.readObject();
 
Normal müsste es ja so sein

Java:
Object eins = os.readObject();

Da ich aber versucht habe, eine ArrayList zu machen, hat java mir die Klasse
selbst erzeugt
 
S

SlaterB

Gast
na dann lösche sie jetzt, falls du noch soviel Macht auf deinem Rechner besitzt,
und füge das zweite r ein: Araylist -> Arraylist
 
:D ja die Klasse hab ich gelöscht

aber

Java:
public void laden() throws ClassNotFoundException{
        System.out.println("Aufruf Laden");
        try{
            FileInputStream fileStream = new FileInputStream("Playlisten.ser");
            ObjectInputStream os = new ObjectInputStream(fileStream);
           
            //Objekte einlesen
            Object eins = os.readObject();
            Object zwei = os.readObject();
 
            
            os.close();
            System.out.println("Laden komplett");
        }catch(IOException ex){
            System.out.println("Ladefehler: Playlisten.ser");
            ex.printStackTrace();
        }
    }

Er zeigt jetzt zwar keine Fehlermeldung, aber wie kann ich denn nun sagen,
dass Object = getPanellist1 ist
 
S

SlaterB

Gast
ich verstehe schon nicht was du damit sagen willst, dann dürfte es ein Compiler auch nicht,
wobei man natürlich darüber streiten kann, wer intelligenter ist ;)

das Objekt unter der Variablen eins dürfte nach wie vor eine ArrayList sein, Casten müsste gehen,
Abspeichern unter einer Variablen geht so wie immer und überall, etwa
> playList.setPanellist1(..);
sofern eine set-Methode da ist
 
N

nillehammer

Gast
Sebi.Schneider hat gesagt.:
Er zeigt jetzt zwar keine Fehlermeldung, aber wie kann ich denn nun sagen,
dass Object = getPanellist1 ist
Serialisierung und anschließende Deserialisierung ist ein symmetrischer Prozess. Du bekommst beim Deserialisieren also genau die selben Objekte in genau der selben Reihenfolge wieder heraus, wie sie hineingeschrieben wurden. Was in welcher Reihenfolge geschrieben wurde, musst Du selbst wissen. Die JVM oder der Compiler wissen das nicht und können Dir hierbei auch nicht helfen. Schaue Dir Deinen Serialisierungscode an:
Java:
os.writeObject(playlist.getPanel1List());
os.writeObject(playlist.getPanel2List());
os.writeObject(playlist.getPanel3List());
os.writeObject(playlist.getPanel4List());
os.writeObject(playlist.getPanel5List());
os.writeObject(playlist.getPanel6List());
os.writeObject(playlist.getPanel7List());
os.writeObject(playlist.getPanel8List());
os.writeObject(playlist.getPanel9List());
Damit dürfte klar sein, dass Du neun Instanzen von ArrayList serialisiert hast, wobei die erste ArrayList aus playlist.getPanel1List() kommt, die zweite aus playlist.getPanel2List() usw. Wie SlaterB schon schrieb, kannst/musst Du mit den ausgelesenen Werten jetzt irgendwas machen, z.B. die nach ArrayList gecasteten Objekte den entsprechenden Feldern wieder zuweisen. Wenn Du Setter implementiert hast, in etwa so:
Java:
ArrayList panelList1 = (ArrayList) os.readObject();
playlist.setPanelList1(panelList1);
 
Zuletzt bearbeitet von einem Moderator:
Das ist nun meine Laden Methode

Java:
public void laden() throws ClassNotFoundException{
        System.out.println("Aufruf Laden");
        try{
            FileInputStream fileStream = new FileInputStream("Playlisten.ser");
            ObjectInputStream os = new ObjectInputStream(fileStream);
           
            //Objekte einlesen
            Object eins = os.readObject();
            Object zwei = os.readObject();
            Object drei = os.readObject();

            
             playlist1 = (ArrayList) eins;
                playlist.setPanel1List(playlist1);
                
             playlist2 = (ArrayList) zwei;
                playlist.setPanel2List(playlist2);
                
             playlist3 = (ArrayList) drei;
                playlist.setPanel3List(playlist3);
                

                
            os.close();
            System.out.println("Laden komplett");
        }catch(IOException ex){
            System.out.println("Ladefehler: Playlisten.ser");
            ex.printStackTrace();
        }
    }

Meine Fehlermeldung: Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

Laden komplett zeigt er mir noch an, also müsste er eig alles richtig geladen haben ???:L
 
S

SlaterB

Gast
anscheinend sind die Listen auf irgendeine Weise in die GUI eingebunden,
GUI-Daten darf man nicht einfach so austauschen, weil der AWT-Thread nebenläufig damit arbeitet,
er liest eine size() > 0, will 2 Schritte später auf das erste Element zugreifen, aber jemand hat die Liste zwischenzeitlich durch eine leere ersetzt -> BAM

lies alle drei Listen in lokale Variablen ein, aber Zeile 13-20 gehören in einen SwingUtilities.invokeLater()-Block,
schlage das nach,
und die Variablen in 8-10 müssen dann final sein

Threading with Swing: SwingUtilities.invokeLater

wobei, gilt nur wenn laden() in einem separaten Thread läuft, startest du einen Thread, doch eher unwahrscheinlich,
oder ist es der main-Thread? wo und wie wird laden() aufgerufen?

wie sieht der StackTrace länger aus, wie und wo werden die Playlists verwendet,
vollständiges Testprogramm könnte helfen
 
Zuletzt bearbeitet von einem Moderator:
in der GUI Klasse verwende ich nur die Playlisten zum anzeigen.
Da wird nichts erstellt.

Java:
public void mouseClicked(MouseEvent e) {
        
        panel = (JPanel) e.getSource();
        System.out.print("Wurde geklickt");

        // Panels von links nach rechts
        // Panel 1 --------------------------------------------------------------------- 
        if (panel.getName().equals("x=0, y=0")) {


            panel.setBackground(new Color(86, 144, 153));
            hauptbox.setBackground(new Color(86, 144, 153));

            mp3Player.play(playlist.getPanel1List().get(0));



Das Laden funktioniert durch ein Button-Klick, ruft er die Methode auf

Den Thread benutz ich in der play() der MP3Klasse
 
S

SlaterB

Gast
tritt denn die Exception an dieser Stelle auf?
es gibt doch normalerweise einen StackTrace, da sieht man die letzten Codezeilen, ist es diese Zeile 14?
natürlich ist auch der Zeitpunkt ein idealer Faktor, tritt die Exception genau bei einem entsprechenden Mausklick auf,
oder genau beim Laden oder sonstwie zufällig?

zu dem Code:
du kannst auch mit Ausgaben vorher anschauen ob die Liste leer ist,
generell sollte doch dein Code so gebaut sein, dass er auch mit einer leeren Liste ohne Exception zurechtkommt,
mit if prüfen

weiterhin schaue nach was denn playlist.getPanel1List() ist, war das beim Programmstart leer,
wann und wo wird mit welcher Sicherheit etwas eingefügt,
was ist im Speziellen beim laden() los, wird dort eine leere playlist1 geladen? ausgeben,
wenn nicht leer, dann wird sie vielleicht irgendwo gesetzt, aber die andere Codestelle greift auf ein zweites Objekt zu wo eine andere leere Liste gesetzt ist,
vollständiges Testprogramm wäre wieder aussagekräftig
 
N

nillehammer

Gast
Hattest Recht,

hab mal um das MouseClick eine IF Abfrage gemacht, ob das Panel leer ist.

es ist leer,

liegt es dann am Speichern?
Im Konstruktor von PlayList werden die ganzen ArrayLists leer initialisiert. Vielleicht greifst Du beim Speichern auf so ein frisch initialisiertes PlayList-Objekt zu. Das ist aber schnell rauszukriegen. Folgende Zeile in der Methode speichern() gibt Aufschluss:
Java:
System.out.println(playlist.getPanel1List());
// dann die ganzen os.writeObject()s
Der Code für's Speichern sieht so aus, als müsste er funktionieren. Du kannst nach dem Speichern ja mal in die .ser-Datei gucken. Die ist zwar sehr kryptisch, aber ein paar lesbare Fetzen findet man da noch. Zum Vergleich mal eine leere ArrayList direkt serialisieren und danach eine, wo was drinnen ist.
 
so hab es mal ausgeben lassen.

Die Ausgabe sieht folgendermaßen aus

System.out.println("Playliste 1: " + playlist.getPanel1List());
Ausgabe: Playliste 1: []


System.out.println("Write Playlist: " + os);
Ausgabe: Write Playlist: osjava.io_ObjectOutputStream@15a0305
 
N

nillehammer

Gast
Code:
System.out.println("Playliste 1: " + playlist.getPanel1List());
Ausgabe: Playliste 1: []
Japp, das heißt, das DIESE Liste schon beim Speichern leer ist und deswegen korrekterweise nach dem Laden auch wieder.
 

Crian

Top Contributor
Ganz ab von deinem Problem, ist

Java:
public Playlist() {
        panel1List = new ArrayList<Track>();
        panel2List = new ArrayList<Track>();
        panel3List = new ArrayList<Track>();
        panel4List = new ArrayList<Track>();
        panel5List = new ArrayList<Track>();
        panel6List = new ArrayList<Track>();
        panel7List = new ArrayList<Track>();
        panel8List = new ArrayList<Track>();
        panel9List = new ArrayList<Track>();
        playlistTrack = new ArrayList<String>();
    }

wirklich dein Ernst? Wo du Schon mit Listen arbeitest? Wie wäre es mit

Java:
    private final int NUMBER_OF_LISTS = 9;

    public Playlist() {
        panelLists = new ArrayList<List<Track>>();
        for (i=0; i<=NUMBER_OF_LISTS; ++i) {
            List<Track> trackList = new ArrayList<Track>();
            panelLists.add(trackList);
        }
        playlistTrack = new ArrayList<String>();
    }
 
Zuletzt bearbeitet:
N

nillehammer

Gast
komisch, denn wenn auf die Playliste zugreife, ist da nämlich was drin
Mag komisch sein, aber System.out.println() lügt nicht. Jedenfalls kannst du Dein Problem jetzt woanders suchen. Das Serialisieren/Deserialisieren dürfte nicht das Problem sein. Für einen Tipp zur Ursache fehlt etwas Kontext. SlaterB hat möglicherweise einen Ansatzpunkt genannt (nebenläufige Zugriffe auf die ArrayLists). Eine andere Ursache könnte sein, dass Du "aus versehen" neue (Playlist-)Objekte oder direkt ArrayLists erzeugtst, wo Du alte weiterverwenden wolltest. Wäre ggf. ein Thema für einen neuen Thread, denke ich.
 

Ähnliche Java Themen

Neue Themen


Oben