2

Trying to serialize and send Lot object to socket. Getting error:

java.io.NotSerializableException: com.server.ClientServiceThread

Why?

public class ClientServiceThread extends Thread  {... // form here called sendObj ...}

public class FlattenLot {
public void sendObj(){
        try {
            out = new ObjectOutputStream(oStream);
            out.writeObject(lot); // error
            out.flush();
            out.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

Lot class:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import java.util.Date;
import java.util.Calendar;

public class Lot implements Serializable{
private static final long serialVersionUID = 1L;
    public ArrayList<ClientServiceThread> clientBidsLog = new ArrayList<ClientServiceThread>();
    public ArrayList<Integer> bidLog = new ArrayList<Integer>();

    private List<Integer> bids = new ArrayList<Integer>();
    private List<ClientServiceThread> clients = new ArrayList<ClientServiceThread>();

    private  String NAME;
    private  int INITIAL_PRICE;

    private int MAX_BID = 0;
    public volatile boolean notAvailable = false;
Lot(String name, int initPrice){
        NAME = name;
        INITIAL_PRICE = initPrice;
    }
public synchronized String getName(){return NAME;}
public synchronized int getInitPrice(){return INITIAL_PRICE;}
public synchronized void subscribe(ClientServiceThread t){
        clients.add(t);
      }
public synchronized void unsubscribe(ClientServiceThread t){
        clients.remove(t);
      }
public  synchronized boolean makeBid(ClientServiceThread t,int i){
          if(i > INITIAL_PRICE && i > MAX_BID){
                clientBidsLog.add(t);
                bidLog.add(i);
                bids.add(i);
                MAX_BID = i;
                t.LAST_BID = i;
                notifyAllSubscribers("New bid: "+this.getMaxBid()+" made by "+this.clientBidsLog.get(this.clientBidsLog.size()-1).CLIENT_NAME);
                return true;
          }else{
                return false;
          }


          }
public synchronized void notifyAllSubscribers(String msg){
        for (ClientServiceThread client : clients){
              client.lotUpdated(this, msg);
            }
    }
public synchronized int getMaxBid(){return MAX_BID;}

    private Date time;

    public Lot() {
        time = Calendar.getInstance().getTime();
    }

    public Date getTime() {
        return time;
    }
    }
8
  • 2
    why would you need to serialize a Thread? Commented Jun 6, 2012 at 3:35
  • I serialize Lot object. The writeObject method called from Thread which sends data to client. Commented Jun 6, 2012 at 3:36
  • 1
    The error says that your ClientServiceThread can't be serialized. Maybe if you post the code where the error arises people community you could have better help. Commented Jun 6, 2012 at 3:38
  • 2
    Is Lot a non-static inner class of ClientServiceThread? Commented Jun 6, 2012 at 3:39
  • 1
    I'll suggest you to redesign your application (if you can). You are trying to serialize the class that holds all your Threads (maybe you just need the data inside Lot, not the Threads in it). In case you can't modify that class, just make your ClientServiceThread implements serializable too, or mark your List<ClientServiceThread> clients and public ArrayList<ClientServiceThread> clientBidsLog as transient. Commented Jun 6, 2012 at 3:42

3 Answers 3

5

The error is caused by trying to serialize a ClientServiceThread, which is not serializable. Somehow one of those is part of a Lot. If Lot is not declared with a ClientServiceThread field (or with a field that contains a ClientServiceThread), then another possibility is that Lot is a non-static inner class of a class that does have such a field. The outer class instance would then be a (hidden) member of Lot.

The solution is to either make ClientServiceThread serializable (not likely, from its name) or else eliminate it from the serialization by marking the relevant field(s) transient (or removing them from the Lot class).

Sign up to request clarification or add additional context in comments.

Comments

4

Lot contains

public ArrayList<ClientServiceThread> clientBidsLog 
private List<ClientServiceThread> clients

If you wish this field to be serialized mark the ClientServiceThread serializable too

if you don't want it to be serialized just mark it transient like

public transient ArrayList<ClientServiceThread> clientBidsLog 
private transient List<ClientServiceThread> clients

2 Comments

Or mark that field as transient to not include it in serialization.
Don't forget the private List<ClientServiceThread> clients attribute.
2

A couple of answers have suggested that you could declare ClientServiceThread serializable as a possible solution.

WARNING - that probably won't work!

Yes, you can declare a Thread subclass that implements Serializable, but the Java serialization mechanism can't serialize the stack of a live thread. In fact, I don't even think it will succeed in serializing an inactive thread's state (e.g. the thread's ThreadGroup reference), so you'll probably end up the more exceptions.

I think your only option is to exclude the threads from serialization by declaring those collections to be transient.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.