0

I am sending serialized object via sockets. Problem is when I send only one string (message) I got this error mentioned on title. So here is class that creates socket object:

package Pinger;

import java.io.*;
import java.util.Vector;

public class ChatMessage implements Serializable {

protected static final long serialVersionUID = 1112122200L;

static final int WHOISIN = 0, MESSAGE = 1, LOGOUT = 2, JOB = 3;
private int type,frequency,maxScans,NUMTHREADS,ttl;
Vector <String> IPS;
private String message;

// constructor
ChatMessage(int type, String message) {
    this.type = type;
    this.message = message;
}
ChatMessage (int type, int frequency, Vector <String> IPS, int maxScans, int NUMTHREADS, int ttl){
    this.type=type;
    this.frequency=frequency;
    this.IPS=IPS;
    this.maxScans=maxScans;
    this.NUMTHREADS=NUMTHREADS;
    this.ttl=ttl;
}

// getters
    .
    .
    .

     }

This class creazes serializable object that will be send over socket. Problem is when I am sending string message (that string is passed to ChatMessage class) I got error that java cannot cast from String to ChatMessage. Also I will give you Client and ClientGUI class to provide you with all you need to understand my code. I really don't know where is error. Can you guys help me with that? Best regards.

package Pinger;

import java.net.*;
import java.io.*;
import java.util.*;
public class Client  {

// for I/O
private ObjectInputStream sInput;       // to read from the socket
private ObjectOutputStream sOutput;     // to write on the socket
private Socket socket;

// if I use a GUI or not
private ClientGUI cg;

// the server, the port and the username
private String server, username;
private int port;

/*
 *  Constructor called by console mode
 *  server: the server address
 *  port: the port number
 *  username: the username
 */
Client(String server, int port, String username) {
    // which calls the common constructor with the GUI set to null
    this(server, port, username, null);
}

/*
 * Constructor call when used from a GUI
 * in console mode the ClienGUI parameter is null
 */
Client(String server, int port, String username, ClientGUI cg) {
    this.server = server;
    this.port = port;
    this.username = username;
    // save if we are in GUI mode or not
    this.cg = cg;
}

/*
 * To start the dialog
 */
public boolean start() {
    // try to connect to the server
    try {
        socket = new Socket(server, port);
    } 
    // if it failed not much I can so
    catch(Exception ec) {
        display("Error connecting to server:" + ec);
        return false;
    }

    String msg = "Connection accepted " + socket.getInetAddress() + ":" + socket.getPort();
    display(msg);

    /* Creating both Data Stream */
    try
    {
        sInput  = new ObjectInputStream(socket.getInputStream());
        sOutput = new ObjectOutputStream(socket.getOutputStream());
    }
    catch (IOException eIO) {
        display("Exception creating new Input/output Streams: " + eIO);
        return false;
    } 
    new ListenFromServer().start();
    try
    {
        sOutput.writeObject(username);
    }
    catch (IOException eIO) {
        display("Exception doing login : " + eIO);
        disconnect();
        return false;
    }
    // success we inform the caller that it worked
    return true;
}

/*
 * To send a message to the console or the GUI
 */
private void display(String msg) {
    if(cg == null)
        System.out.println(msg);      // println in console mode
    else
        cg.append(msg + "\n");      // append to the ClientGUI JTextArea (or whatever)
}

/*
 * To send a message to the server
 */
void sendMessage(ChatMessage msg) {
    try {
        System.out.println(msg);
        sOutput.writeObject(msg);
    }
    catch(IOException e) {
        display("Exception writing to server: " + e);
    }
}

/*
 * When something goes wrong
 * Close the Input/Output streams and disconnect not much to do in the catch clause
 */
private void disconnect() {
    try { 
        if(sInput != null) sInput.close();
    }
    catch(Exception e) {} // not much else I can do
    try {
        if(sOutput != null) sOutput.close();
    }
    catch(Exception e) {} // not much else I can do
    try{
        if(socket != null) socket.close();
    }
    catch(Exception e) {} // not much else I can do

    // inform the GUI
    if(cg != null)
        cg.connectionFailed();

}
class ListenFromServer extends Thread {

    public void run() {
        while(true) {
            try {
                ChatMessage msg = (ChatMessage) sInput.readObject();
                //if (nesto instanceof String)
                //msg = (String) sInput.readObject();
                //}
                // if console mode print the message and add back the prompt
                if(cg == null) {
                    System.out.println(msg.getMessage());
                    System.out.print("> ");
                }
                else {
                    cg.append(msg.getMessage());
                }
            }
            catch(IOException e) {
                display("Server has close the connection: " + e);
                if(cg != null) 
                    cg.connectionFailed();
                break;
            }
            // can't happen with a String object but need the catch anyhow
            catch(ClassNotFoundException e2) {
            }
        }
    }
}
}

Also here is GUI class for class client:

package Pinger;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.InetAddress;
import java.net.UnknownHostException;


/*
 * The Client with its GUI
 */
public class ClientGUI extends JFrame implements ActionListener {

private static final long serialVersionUID = 1L;
// will first hold "Username:", later on "Enter message"
private JLabel label;
// to hold the Username and later on the messages
private JTextField tf;
// to hold the server address an the port number
private JTextField tfServer, tfPort;
// to Logout and get the list of the users
private JButton login, logout, whoIsIn;
// for the chat room
private JTextArea ta;
// if it is for connection
private boolean connected;
// the Client object
private Client client;
// the default port number
private int defaultPort;
private String defaultHost;
InetAddress ComputerIP;

// Constructor connection receiving a socket number
ClientGUI(String host, int port) throws UnknownHostException {

    super("Chat Client");
    defaultPort = port;
    defaultHost = host;

    // The NorthPanel with:
    JPanel northPanel = new JPanel(new GridLayout(3,1));
    // the server name anmd the port number
    JPanel serverAndPort = new JPanel(new GridLayout(1,5, 1, 3));
    // the two JTextField with default value for server address and port number
    tfServer = new JTextField(host);
    tfPort = new JTextField("" + port);
    tfPort.setHorizontalAlignment(SwingConstants.RIGHT);

    serverAndPort.add(new JLabel("Server Address:  "));
    serverAndPort.add(tfServer);
    serverAndPort.add(new JLabel("Port Number:  "));
    serverAndPort.add(tfPort);
    serverAndPort.add(new JLabel(""));
    // adds the Server an port field to the GUI
    northPanel.add(serverAndPort);

    // the Label and the TextField
    ComputerIP = InetAddress.getLocalHost();
    label = new JLabel("Enter your username below", SwingConstants.CENTER);
    northPanel.add(label);
    tf = new JTextField(ComputerIP.toString());
    tf.setBackground(Color.WHITE);
    northPanel.add(tf);
    add(northPanel, BorderLayout.NORTH);

    // The CenterPanel which is the chat room
    ta = new JTextArea("Clients logs\n", 80, 80);
    JPanel centerPanel = new JPanel(new GridLayout(1,1));
    centerPanel.add(new JScrollPane(ta));
    ta.setEditable(false);
    add(centerPanel, BorderLayout.CENTER);

    // the 3 buttons
    login = new JButton("Login");
    login.addActionListener(this);
    logout = new JButton("Logout");
    logout.addActionListener(this);
    logout.setEnabled(false);       // you have to login before being able to logout
    whoIsIn = new JButton("Who is in");
    whoIsIn.addActionListener(this);
    whoIsIn.setEnabled(false);      // you have to login before being able to Who is in

    JPanel southPanel = new JPanel();
    southPanel.add(login);
    southPanel.add(logout);
    southPanel.add(whoIsIn);
    add(southPanel, BorderLayout.SOUTH);

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(600, 600);
    setVisible(true);
    tf.requestFocus();

}

// called by the Client to append text in the TextArea 
void append(String str) {
    ta.append(str);
    ta.setCaretPosition(ta.getText().length() - 1);
}
// called by the GUI is the connection failed
// we reset our buttons, label, textfield
void connectionFailed() {
    login.setEnabled(true);
    logout.setEnabled(false);
    whoIsIn.setEnabled(false);
    InetAddress localIP = null;
    label.setText("Enter your username below");
    try {
        localIP=InetAddress.getLocalHost();
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    tf.setText(localIP.getHostAddress().toString());
    // reset port number and host name as a construction time
    tfPort.setText("" + defaultPort);
    tfServer.setText(defaultHost);
    // let the user change them
    tfServer.setEditable(false);
    tfPort.setEditable(false);
    // don't react to a <CR> after the username
    tf.removeActionListener(this);
    connected = false;
}

/*
* Button or JTextField clicked
*/
public void actionPerformed(ActionEvent e) {
    Object o = e.getSource();
    // if it is the Logout button
    if(o == logout) {
        client.sendMessage(new ChatMessage(ChatMessage.LOGOUT, ""));
        return;
    }
    // if it the who is in button
    if(o == whoIsIn) {
        client.sendMessage(new ChatMessage(ChatMessage.WHOISIN, ""));               
        return;
    }

    // ok it is coming from the JTextField
    if(connected) {
        // just have to send the message
        client.sendMessage(new ChatMessage(ChatMessage.MESSAGE, tf.getText()));             
        tf.setText("");
        return;
    }


    if(o == login) {
        // ok it is a connection request
        String username = tf.getText().trim();
        // empty username ignore it
        if(username.length() == 0)
            return;
        // empty serverAddress ignore it
        String server = tfServer.getText().trim();
        if(server.length() == 0)
            return;
        // empty or invalid port numer, ignore it
        String portNumber = tfPort.getText().trim();
        if(portNumber.length() == 0)
            return;
        int port = 0;
        try {
            port = Integer.parseInt(portNumber);
        }
        catch(Exception en) {
            return;   // nothing I can do if port number is not valid
        }

        // try creating a new Client with GUI
        client = new Client(server, port, username, this);
        // test if we can start the Client
        if(!client.start()) 
            return;
        tf.setText("");
        label.setText("Enter your message below");
        connected = true;

        // disable login button
        login.setEnabled(false);
        // enable the 2 buttons
        logout.setEnabled(true);
        whoIsIn.setEnabled(true);
        // disable the Server and Port JTextField
        tfServer.setEditable(false);
        tfPort.setEditable(false);
        // Action listener for when the user enter a message
        tf.addActionListener(this);
    }

}

// to start the whole thing the server
public static void main(String[] args) throws UnknownHostException {
    new ClientGUI("localhost", 6000);
}

}

EDIT 1: Added expection stacktrace

Exception in thread "Thread-2" java.lang.ClassCastException: java.lang.String cannot be 
cast to Pinger.ChatMessage
    at Pinger.Client$ListenFromServer.run(Client.java:143)
3
  • 1
    please post exception stacktrace Commented Jun 4, 2013 at 7:51
  • Added exception stacktrace. Thank your for letting me know. Commented Jun 4, 2013 at 7:55
  • So you are sending a String and trying to read it as a ChatMessage. Too localized. Commented Jun 4, 2013 at 10:29

2 Answers 2

1

What about this:

sOutput.writeObject(username);

the first thing you send to the server is a String and at the server side you assume you are gettig a ChatMessage.

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

3 Comments

This is the only time when I send string. Also when I submit message (aka write it and send it) i got error. Username is broadcasted when Client is connecting and that part is working fine. I ll try to change that... Will let you know
I added to my code that program send SendMessage object instead of String and I still got same error.
Try not to post summaries when you want analysis and help. "I added to my code that program send SendMessage object instead of String" does not tell us exactly what you did; identify the line in the post and post the code that you replaced it with, or something like that.
0

Sorry guys for bothering your. Problem was in Server class that I didnt showed here(my bad). I was sending String insted of ChatMessage object via socket. That's why I got error. I didn't notice that earlier... Sorry for taking your time. Problem was in Server class which broadcast message to all Clients. There ObjectInputStream was casted to String insted of ChatMessage(). One more time sorry for bothering your... Really my bad...

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.