2011-09-27 65 views
1

我試圖通過套接字連接發送一個自定義的對象。該類實現可串行化,但是當試圖將對象寫入套接字時,構造函數仍會拋出NotSerializableException。我會張貼以下相關的代碼:通過套接字發送可序列化對象時發生NotSerializableException異常?

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

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

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

這是我的定製課程。現在我試圖從服務器發送一個數組列表到客戶端,但我會在後面的階段添加更多信息。發送方法貼在我的服務器類下面是張貼如下:

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(); 
    } 

} 

這是我從服務器的發送方法。 clientCollection是im試圖發送的arrayList。

整個客戶端類:

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"); 
} 

}

新的堆棧跟蹤:

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) 
+2

類'Gesäll.Client'不可序列化。它需要整個serilizableArrayHolder類可序列化。 –

回答

5

其中可達通過serilizableArrayHolder所有類都必須Serializable包括你Client類。

Client類包含SocketThreadDataInputStreamDataOutputStreamObjectOutputStream成員。他們都不是Serializable。這就是爲什麼你不能序列化Client類。這是另一個answer with the same topic

我認爲你應該重新考慮你的設計,並分享爲什麼要序列化這些對象。

+0

好吧,所有我試圖完成的事情是將arrayList從服務器發送到客戶端。爲了澄清,我目前的設計是,當用戶使用我的主應用程序連接到服務器時,服務器創建類Client的實例,並將「Client」實例添加到ArrayList。然後,這個數組列表將包含所有「在線」客戶端的參考。至於現在,我的可serilizableArrayHolder只接受arraylist,但我的計劃是使其通用接受其他對象以及 –

+0

爲什麼你發送ClientList給你的客戶?你的客戶是否必須相互溝通?如果他們這樣做,他們應該做點對點或通過服務器? – palacsint

7

異常告訴你這個問題。您的Client類不可序列化。要序列化一個對象,它所引用的所有對象(等等,可傳遞)也需要可序列化。如果您不想將其序列化,則可以標記參考transient

+0

謝謝。我已經使客戶端類可以被serilizable了,但是它仍然會拋出同樣的錯誤。從我可以告訴ArrayList不可以serilizable,這可能會導致錯誤。我創建時試圖創建我的ArrayList瞬態,但仍產生一個異常 –

+1

@JimmyGustafsson:'ArrayList'是'Serializable',請檢查[javadoc](http://download.oracle.com/javase/6/docs/ API/JAVA/util的/ ArrayList.html)。發佈你的'客戶'類也是如此。 – palacsint

+2

@Jimmy Gustafsson如果你有相同的異常和消息,你沒有部署該類的可序列化版本。如果您使用新消息得到相同的異常,則會命名另一個不可序列化的類。 – EJP