rodit
rodit

Reputation: 1766

NotSerializableException serializing class that implements Serializable

I am having trouble serializing this class using the ObjectOutputStream#writeObject method.

Here is my class:

public class InteractedObject implements Serializable{

    private static final long serialVersionUID = 537798409913313981L;

    protected int id;
    protected WorldTile tile;
    protected int option;

    private long interactionTime;

    public InteractedObject(int id, WorldTile tile, int option){
        this.id = id;
        this.tile = tile;
        this.option = option;
    }

    public long getInteractionTime(){
        return interactionTime;
    }

    public void setInteractionTime(long interactionTime){
        this.interactionTime = interactionTime;
    }

    public boolean isEqualTo(Object o){
        if(this == o)
            return true;
        InteractedObject obj = o instanceof InteractedObject ? (InteractedObject)o : null;
        if(obj == null)
            return false;
        return obj.id == id && obj.tile.equals(tile) && obj.option == option;
    }
}

The WorldTile class definitely implements the Serializable interface and only uses fields with types short and byte. I cannot see why this throws a NotSerializableException for my class 'a.rodit.rs.InteractedObject' (the top one).

Any help or guidance about why this is happening would be appreciated.

EDIT:

My WorldTile class is as follows:

public class WorldTile implements Serializable {

    private static final long serialVersionUID = -6567346497259686765L;

    private short x, y;
    private byte plane;

    public WorldTile(){
        this(0, 0, 0);
    }

    public WorldTile(int x, int y, int plane) {
        this.x = (short) x;
        this.y = (short) y;
        this.plane = (byte) plane;
    }
    public final WorldTile getLocation() {
        WorldTile tile = new WorldTile(x, y, plane);
        return tile;
    }
    public WorldTile(WorldTile tile) {
        this.x = tile.x;
        this.y = tile.y;
        this.plane = tile.plane;
    }

    public WorldTile(WorldTile tile, int randomize) {
        this.x = (short) (tile.x + Utils.getRandom(randomize * 2) - randomize);
        this.y = (short) (tile.y + Utils.getRandom(randomize * 2) - randomize);
        this.plane = tile.plane;
    }

    public void moveLocation(int xOffset, int yOffset, int planeOffset) {
        x += xOffset;
        y += yOffset;
        plane += planeOffset;
    }

    public final void setLocation(WorldTile tile) {
        setLocation(tile.x, tile.y, tile.plane);
    }

    public final void setLocation(int x, int y, int plane) {
        this.x = (short) x;
        this.y = (short) y;
        this.plane = (byte) plane;
    }

    public int getX() {
        return x;
    }

    public int getXInRegion() {
        return x & 0x3F;
    }

    public int getYInRegion() {
        return y & 0x3F;
    }

    public int getY() {
        return y;
    }

    public int getPlane() {
        if (plane > 3)
            return 3;
        return plane;
    }

    public int getChunkX() {
        return (x >> 3);
    }

    public int getChunkY() {
        return (y >> 3);
    }

    public int getRegionX() {
        return (x >> 6);
    }

    public int getRegionY() {
        return (y >> 6);
    }

    public int getRegionId() {
        return ((getRegionX() << 8) + getRegionY());
    }

    public int getLocalX(WorldTile tile, int mapSize) {
        return x - 8 * (tile.getChunkX() - (Settings.MAP_SIZES[mapSize] >> 4));
    }

    public int getLocalY(WorldTile tile, int mapSize) {
        return y - 8 * (tile.getChunkY() - (Settings.MAP_SIZES[mapSize] >> 4));
    }

    public int getLocalX(WorldTile tile) {
        return getLocalX(tile, 0);
    }

    public int getLocalY(WorldTile tile) {
        return getLocalY(tile, 0);
    }

    public int getLocalX() {
        return getLocalX(this);
    }

    public int getLocalY() {
        return getLocalY(this);
    }

    public int get18BitsLocationHash() {
        return getRegionY() + (getRegionX() << 8) + (plane << 16);
    }

    public int get30BitsLocationHash() {
        return y + (x << 14) + (plane << 28);
    }

    public boolean withinDistance(WorldTile tile, int distance) {
        if (tile.plane != plane)
            return false;
        int deltaX = tile.x - x, deltaY = tile.y - y;
        return deltaX <= distance && deltaX >= -distance && deltaY <= distance
                && deltaY >= -distance;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + plane;
        result = prime * result + x;
        result = prime * result + y;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        WorldTile other = (WorldTile) obj;
        if (plane != other.plane)
            return false;
        if (x != other.x)
            return false;
        if (y != other.y)
            return false;
        return true;
    }

    public boolean withinDistance(WorldTile tile) {
        if (tile.plane != plane)
            return false;
        // int deltaX = tile.x - x, deltaY = tile.y - y;
        return Math.abs(tile.x - x) <= 15 && Math.abs(tile.y - y) <= 15;// deltaX
                                                                        // <= 14
                                                                        // &&
                                                                        // deltaX
                                                                        // >=
                                                                        // -15
                                                                        // &&
                                                                        // deltaY
                                                                        // <= 14
                                                                        // &&
                                                                        // deltaY
                                                                        // >=
                                                                        // -15;
    }

    public int getCoordFaceX(int sizeX) {
        return getCoordFaceX(sizeX, -1, -1);
    }

    public static final int getCoordFaceX(int x, int sizeX, int sizeY,
            int rotation) {
        return x + ((rotation == 1 || rotation == 3 ? sizeY : sizeX) - 1) / 2;
    }

    public static final int getCoordFaceY(int y, int sizeX, int sizeY,
            int rotation) {
        return y + ((rotation == 1 || rotation == 3 ? sizeX : sizeY) - 1) / 2;
    }

    public int getCoordFaceX(int sizeX, int sizeY, int rotation) {
        return x + ((rotation == 1 || rotation == 3 ? sizeY : sizeX) - 1) / 2;
    }

    public int getCoordFaceY(int sizeY) {
        return getCoordFaceY(-1, sizeY, -1);
    }

    public int getCoordFaceY(int sizeX, int sizeY, int rotation) {
        return y + ((rotation == 1 || rotation == 3 ? sizeX : sizeY) - 1) / 2;
    }

}

As I mentioned previously, I don't see any problem with it.

Upvotes: 1

Views: 157

Answers (1)

Krasimir Stoev
Krasimir Stoev

Reputation: 1754

NotSerializableException is only thrown when some object to be serialized does not implement the java.io.Serializable interface

I tried to simulate the issue and copied your class. Then I created a sample WorldTile class that looks like that:

public class WorldTile implements Serializable {

    short x = 4;
    byte y = 1;
}

My piece of code is as follows and it works well:

File file = new File("obj.txt");
file.createNewFile();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(new InteractedObject(4, new WorldTile(), 5));
System.out.println("success");

The only reason for you to fail to achieve this is probably your WorldTile class.

EDIT:

Another problem can be if you have failed to run the latest version of your file. Have you saved all the .java files in your application?

Also are you sure that your Serializable interface you have implemented is indedd java.io.Serializable ?

Upvotes: 1

Related Questions