2011-09-27 2 views
1

소켓 연결을 통해 맞춤형 개체를 보내려고합니다. 이 클래스는 serializable을 구현하지만 소켓에 객체를 쓰려고 할 때 생성자는 여전히 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; 
    } 
} 

이것은 내 맞춤 수업입니다. 지금은 서버에서 클라이언트로 arraylist를 보내려고하지만 나중에 나중에 추가 정보를 추가하겠습니다. 아래에 게시 된 내 서버 클래스의 send 메서드는 다음과 같습니다.

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은 보내는 것을 시도하는 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"); 
} 

}

새로운 스택 트레이스 : serilizableArrayHolder을 통해 연결할 수

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

모든 클래스가이 Client 클래스를 포함 Serializable합니다.

귀하의 Client 클래스는 Socket, Thread, DataInputStream, DataOutputStreamObjectOutputStream 멤버가 포함되어 있습니다. 그들 중 누구도 Serializable입니다. 그래서 Client 클래스를 직렬화 할 수 없습니다. 다른 answer with the same topic이 있습니다.

디자인을 재고하고이 객체를 직렬화하려는 이유를 공유해야한다고 생각합니다.

+0

글쎄, 노력하고있는 모든 노력은 서버에서 클라이언트에게 arrayList를 보내는 것입니다. 명확히하기 위해 현재 설계는 사용자가 내 응용 프로그램을 사용하여 서버에 연결할 때 서버가 클래스 Client의 인스턴스를 만들고 "Client"인스턴스를 ArrayList에 추가하는 것입니다. 그런 다음 그 arraylist는 모든 "온라인"클라이언트에 대한 참조를 포함하게됩니다. 현재로서는 내 serilizableArrayHolder는 arraylists 만 받아 들일 수 있지만 내 계획은 다른 객체도 받아 들일 수 있도록 일반화하는 것입니다. –

+0

왜 ClientList를 클라이언트에 보냅니 까? 고객이 서로 의사 소통해야합니까? 그들은 피어 투 피어 (peer to peer) 또는 서버를 통해해야합니까? – palacsint

7

예외는 문제를 알려줍니다. Client 클래스는 직렬화 할 수 없습니다. 객체를 직렬화하려면 참조하는 모든 객체 (등)를 직렬화 할 수 있어야합니다. 직렬화하지 않으려면 transient 참조를 표시 할 수 있습니다.

+0

감사합니다. Client 클래스를 이제는 serilizable로 만들었지 만 여전히 같은 오류가 발생합니다. 내가 뭘 알 수에서 ArrayList는 오류가 발생할 수 있습니다 serilizable되지 않습니다. 나는 arraylist를 생성 할 때 일시적으로 만들려고했지만 여전히 예외를 생성한다. –

+1

@JimmyGustafsson : ArrayList는 Serializable이며, javadoc을 확인한다. (http://download.oracle.com/javase/6/docs/ api/java/util/ArrayList.html). 'Client' 클래스도 게시하십시오. – palacsint

+2

@Jimmy Gustafsson 동일한 예외가 발생하고 클래스의 직렬화 가능 버전을 배포하지 않았다는 메시지가 표시되면 새 메시지에서 동일한 예외가 발생하면 직렬화 할 수없는 다른 클래스의 이름을 지정합니다. – EJP