1

Im trying to send a custom-made object over a socket connection. The class implements serializable but the constructor still throws a NotSerializableException when im trying to write the object to the socket. I'll post relevent code below:

public class serilizableArrayHolder implements Serializable {
   private ArrayList<Client> array= null;

   public serilizableArrayHolder(ArrayList<Client> array) {
       this.array=array;
   }

   public ArrayList<Client> getArray() {
     return array;
   }
}

This is my custom-made class. For now im trying to send an arraylist from the server to the client but i'll add additional info in a later stage. The send method is posted below in my server class is posted below:

public void sendData(Socket clientSocket){
    ObjectOutputStream out;

    try {
        serilizableArrayHolder temp = new serilizableArrayHolder(clientCollection);
        out = new ObjectOutputStream(clientSocket.getOutputStream());
        out.writeObject(temp);   <---This line generates the error.
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

This is my send-method from the server. clientCollection is the arrayList that im trying to send.

The whole Client class:

public class Client implements Runnable, Serializable{
    public Thread thread = new Thread(this);
    private Socket s;
    private DataInputStream in;
    private DataOutputStream out;
    private ObjectOutputStream objOut;
    private ServerMain server=null;
    private String host=null;
    private Client c;
    private String userName;

public Client(Socket s, String host, ServerMain server) throws IOException{
    c=this;
    this.host=host;
    this.s=s;
    this.server=server;
    this.userName=userName;

    in= new DataInputStream(s.getInputStream());
    out=new DataOutputStream(s.getOutputStream());
    objOut=new ObjectOutputStream(s.getOutputStream());
    thread.start();
}

public String getClientInfo(){
    return host;
}
public String getUserName(){
    return userName;
}
public void send(String s){
    try {
        out.writeUTF(s);
        } 
    catch (IOException e){
    }
}

public void run() {

    while(true){
        try {
            String temp = in.readUTF();
            if(temp.equals("sendOnline")){
                sendOnline();
            }

            String tempHost=s.getInetAddress().getHostAddress();

            server.appendString(tempHost+" Skickade: "+temp+"\n");

            }
            catch (IOException e) {
                String str = s.getInetAddress().getHostName();
                server.clientDisconnect(str);
                break;
                }
        }

        try {
            s.close();
            } 
        catch (IOException e) {
                        }

}
public void sendOnline(){
    serilizableArrayHolder temp = new serilizableArrayHolder(server.getClients());
    try {
        objOut.writeObject(temp);
        objOut.flush();
    } catch (IOException e) {

        e.printStackTrace();
        }
            System.out.println("Metoden anropas");
}

}

The new stacktrace:

java.io.NotSerializableException: java.io.DataInputStream
Metoden anropas
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at java.util.ArrayList.writeObject(ArrayList.java:710)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at Gesäll.Client.sendOnline(Client.java:83)
    at Gesäll.Client.run(Client.java:58)
    at java.lang.Thread.run(Thread.java:722)
eightShirt
  • 1,457
  • 2
  • 15
  • 29
John Snow
  • 5,214
  • 4
  • 37
  • 44

2 Answers2

7

The exception tells you the problem. Your Client class is not serializable. To serialize an object, all the objects it references (and so on, transitively) need to also be serializable. You can mark a reference transient if you don't want it to be serialized.

dty
  • 18,795
  • 6
  • 56
  • 82
  • Thanks. I've made the Client class serilizable aswell now, but it still throws the same error. From what I can tell ArrayList isn't serilizable which might cause the error. I did try to make my arraylist transient when creating it but still generates an exception – John Snow Sep 27 '11 at 16:44
  • 1
    @JimmyGustafsson: `ArrayList` is `Serializable`, check the [javadoc](http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html). Post your `Client` class too. – palacsint Sep 27 '11 at 22:03
  • 2
    @Jimmy Gustafsson if you got the same exception and message you didn't deploy the serializable version of the class. If you got the same exception with a new message it names another class that isn't serializable. – user207421 Sep 27 '11 at 23:46
  • I've added my client class and "the new stacktrace". As far as I can see both my client class and serilizableArrayHolder should be serilizable – John Snow Sep 28 '11 at 11:15
5

All classes which are reachable through serilizableArrayHolder have to be Serializable including your Client class.

Your Client class contains Socket, Thread, DataInputStream, DataOutputStream and ObjectOutputStream members. None of them are Serializable. That's why you cannot serialize the Client class. Here is another answer with the same topic.

I think you should rethink your design and share why are you want to serialize these objects.

Community
  • 1
  • 1
palacsint
  • 28,416
  • 10
  • 82
  • 109
  • well, all that im trying to acomplish is to send the arrayList from the server, to the client. To clarify, my current design is that the server creates a instance of the class Client when a user connects to the server using my main application, and add the "Client" instance to a ArrayList. That arraylist will then contain refrences to all the "online" clients. As for now, my serilizableArrayHolder only accepts arraylists, but my plan is to make it generic to accept other objects aswell – John Snow Sep 28 '11 at 13:08
  • Why are you sending the ClientList to you clients? Do your clients have to communicate with each other? If they do should they do it peer to peer or through the server? – palacsint Sep 28 '11 at 19:53