-1

I am trying to serialize an object and my program keeps throwing java.io.NotSerializableException. I followed a few online tutorials and I'm unsure what I am doing wrong.

here is my class where my serialization methods are

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class Save {

    public static ArrayList<String> Saves = new ArrayList<String>();
    private static final String filePath = "/Users/carlgombert/eclipse-workspace/CerberusCryptSwing/saves/";

    public Save() {
    
    }

    public void SaveGame(String name) throws FileNotFoundException, IOException{
        String fileName = (filePath + name + ".svr");
        FileOutputStream userSaveFile = new FileOutputStream(fileName);
        ObjectOutputStream playerSaver = new ObjectOutputStream(userSaveFile);
        playerSaver.writeObject(Main.player);
        userSaveFile.close();
        playerSaver.close();
        LoadGame(name);
    }

    public void LoadGame(String name) throws FileNotFoundException, IOException{
        String fileName = (filePath + name + ".svr");
        FileInputStream userLoadFile = new FileInputStream(fileName); 
        ObjectInputStream playerLoader = new ObjectInputStream(userLoadFile);
        try {
            Main.player = (Player)playerLoader.readObject();
        } catch (ClassNotFoundException | IOException e) {
            e.printStackTrace();
        }
        userLoadFile.close();
        playerLoader.close();
        System.out.println(Main.player);
    }
}

and here is my class I am trying to serialize(most of the code here doesn't matter to the issue)

import java.io.Serializable;
import java.util.*;

public class Player implements Serializable{
    static ArrayList<Weapon> weapons = new ArrayList<Weapon>();
    static ArrayList<Consumable> consumables = new ArrayList<Consumable>();
    private int health;
    private int gold;
    private static int damage;
    private Location location;
    private static final long serialVersionUID = 3L;
    
    public Player(int health, int gold, Location location){
        this.health = health;
        this.gold = gold;
        this.location = location;
        damage = 20;
    }
    
    public Location getLocation(){
        return location;
    }
    
    public void setLocation(Location location){
        this.location = location;
    }
    
    public int getDamage(){
        return damage;
    }
    
    public int getHealth(){
        return health;
    }
    
    public void setHealth(int health){
        this.health = health;
        if(this.health > 100){
            this.health = 100;
        }
    }
    
    public int getGold(){
        return gold;
    }
    
    public void setGold(int gold){
        this.gold = gold;
    }
    
    public void addGold(int gold){
        this.gold += gold;
    }
    
    public void addConsumable(Consumable consumable){
        consumables.add(consumable);
    }
    
    public void clearConsumables(){
        consumables.clear();
    }
    
    public void wipeInventory(){
        consumables.clear();
        weapons.clear();
    }
    
    public void eat(int i){
        health += consumables.get(i).getHealing();
        if(health > 100){
            health = 100;
        }
        consumables.remove(i);
    }
    
    public void consumableMenu(){
        int i = 0;
        for(Consumable x: consumables){
            System.out.println("[" + (i + 1) + "]" + x.getName() + "(healing: " + x.getHealing() + ")");
            i++;
        }
    }
    
    public void damage(int damage){
        health = health - damage;
    }
    
    public void attack(Mob mob){
        mob.damage(damage);
    }
    
    
    public void inventory(){
        if(weapons.size() == 0 && consumables.size() == 0){
            System.out.println("empty");
        }
        else{
            for(Weapon x: weapons){
                System.out.println(x);
            }
            for(Consumable x: consumables){
                System.out.println(x);
            }
        }
    }
    
    public static void addWeapon(Weapon weapon){
        weapons.add(weapon);
    }
    
    public String toString() {
        return "health: " + health + ", gold: " + gold;
    }
}

and here is where I am calling the method from

if(e.getSource()==saveEnterButton) {
            try {
                save.SaveGame(saveTextField.getText());
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            saveTextField.setText("");
        }

here is the error message it throws

java.io.NotSerializableException: sun.awt.image.ToolkitImage
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1197)
    at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1582)
    at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1539)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1448)
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1191)
    at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1582)
    at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1539)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1448)
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1191)
    at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
    at com.cerberuscryptswing.main.Save.SaveGame(Save.java:24)
    at com.cerberuscryptswing.main.Frame.actionPerformed(Frame.java:245)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
    at java.desktop/java.awt.Component.processEvent(Component.java:6391)
    at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

I'm sorry for the lack of comments in my code, can anyone help me to resolve this issue?

  • 1
    When you have a question about an exception, you should include the exception in your question. Usually, a `NotSerializableException` includes the problematic class in its message. As a general advice, you should not “handle” exceptions by catching and printing them and proceeding as if nothing happened. And use [try-with-resources](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) to close streams rather than manual `close()` calls. And do not use dice for deciding whether a variable should be `static` or not. – Holger Oct 20 '22 at 16:46
  • go to this link: [https://stackoverflow.com/questions/6576914/notserializableexception-for-toolkitimage-when-serializing-a-model-in-swing](https://stackoverflow.com/questions/6576914/notserializableexception-for-toolkitimage-when-serializing-a-model-in-swing) – Sajjad Rezai Oct 20 '22 at 17:25
  • Static fields don't belong to the object and won't get serialized. – Nathan Hughes Oct 20 '22 at 18:10
  • There are three `writeObject0()` calls in your stacktrace. The problem therefore must be an object indirectly referenced from your `Player` class (`Player` - some intermediate class - `Image` or `ToolkitImage`). Probably a field in the `Location` class. The objects in the `weapons` and `consumables` lists are irrelevant - these are static fields that are not serialized. – Thomas Kläger Oct 20 '22 at 18:10

1 Answers1

0

I'm not really an Expert on this issue, but when serializing an object in Java every object that you created must implement Serializable. As I've understood, this interface is responsible for the 'Serializer' to know the blueprint of your custom object. You are using Weapon and Consumable (I assume those are your objects) and maybe these classes don't implement 'Serializable'. Might be worth checking this :)