Sorry if this is a 'duh' question, this is my first time on Stack Overflow. My question is, I keep getting a null pointer exception in my code, and I have no idea how to fix it.
java.lang.NullPointerException
at client.ChatClientRMI.append(ChatClientRMI.java:76)
at server.ChatServerRMI.sendTo(ChatServerRMI.java:38)
at server.ChatServerRMI.sendToAll(ChatServerRMI.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
...
My code is designed as follows: my server keeps track of clients connected to it, my clients can send messages to all other clients by using RMI to call the method 'sendToAll()', which appends that message to all clients' JTextAreas. In case you are wondering, I have been running RMI Registry and I have obtained the stubs from the rmic tool shipped with the Java JDK. I am using Notepad++ with Command Prompt on Windows XP if that matters. I have also researched this on many websites and have not found an answer. My server code is below:
package server;
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import server.*;
import java.rmi.*;
import java.rmi.server.*;
import client.*;
public class ChatServerRMI extends UnicastRemoteObject implements ChatRemote{
private JFrame frame;
private JTextArea area;
private ArrayList<ChatClientRMI> clients = new ArrayList<ChatClientRMI>();
public ChatServerRMI() throws RemoteException{
try{
frame = new JFrame("ChatterBox Server -- IP: "+InetAddress.getLocalHost().getHostAddress());
}catch(Exception ex){
frame = new JFrame("ChatterBox Server");
}
area = new JTextArea(10,40);
area.setLineWrap(true);
area.setEditable(false);
frame.getContentPane().add(BorderLayout.CENTER, new JScrollPane(area));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void registerMe(ChatClientRMI me){
clients.add(me);
}
public void go(){
}
public void sendTo(ChatClientRMI from, String s, java.util.List<ChatClientRMI> to){
for(ChatClientRMI c : to){
System.out.println(c.append(from.toString()+": "+s));
//c.append(from.toString()+": "+s);
}
}
public void sendToAll(ChatClientRMI from, String s){
sendTo(from, s, clients);
}
public void add(ChatClientRMI client){
clients.add(client);
}
public ArrayList<ChatClientRMI> getClients(){
return clients;
}
public static void main(String[] args){
try{
ChatServerRMI chat = new ChatServerRMI();
//ChatRemote stub = (ChatRemote) UnicastRemoteObject.exportObject(chat, 12345);
Naming.rebind("rmi://127.0.0.1/ChatterBoxServer", chat);
chat.go();
/*}catch(AlreadyBoundException ex){
System.out.println("Already bound");*/
}catch(Exception ex){
System.out.println("Sorry, but the initializing failed.");
ex.printStackTrace();
}
}
}
My client code is here:
package client;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.awt.event.*;
import java.awt.*;
import server.*;
import java.util.*;
import java.rmi.*;
public class ChatClientRMI implements Serializable{
public static final long serialVersionUID = -3528211100794109108L;
private JFrame frame;
private JTextField input;
private JTextArea output;
private JButton button;
private JPanel inputPanel, outputPanel;
private Container panel;
private String username;
private JMenuBar menuBar;
private JMenu menu;
private JMenuItem menuItem;
private JList<ChatClientRMI> list;
private Vector<ChatClientRMI> clients = new Vector<ChatClientRMI>();
private ChatRemote remote;
public ChatClientRMI(String user){
username = user;
}
public void go(String ip){
try{
remote = (ChatRemote) Naming.lookup("rmi://"+ip+"/ChatterBoxServer");
remote.registerMe(this);
}catch(Exception ex){ex.printStackTrace(); System.exit(0);}
frame = new JFrame("ChatterBox client");
panel = frame.getContentPane();
//panel = new JPanel();
//panel.setLayout(new BorderLayout());
inputPanel = new JPanel();
outputPanel = new JPanel();
input = new JTextField(20);
inputPanel.add(input);
button = new JButton("Send");
inputPanel.add(button);
EnterListener el = new EnterListener();
button.addActionListener(el);
input.addActionListener(el);
output = new JTextArea(10,40);
output.setLineWrap(true);
output.setEditable(false);
list = new JList<ChatClientRMI>(clients);
outputPanel.add(new JScrollPane(output));
outputPanel.add(new JScrollPane(list));
panel.add(outputPanel, BorderLayout.NORTH);
panel.add(inputPanel, BorderLayout.SOUTH);
menuBar = new JMenuBar();
menu = new JMenu("Server");
menuItem = new JMenuItem("Host a server");
menuItem.addActionListener(new HostListener());
menu.add(menuItem);
menuItem = new JMenuItem("Connect to a different server");
menuItem.addActionListener(new ConnectListener());
menu.add(menuItem);
menuBar.add(menu);
frame.setJMenuBar(menuBar);
//frame.setContentPane(panel);
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Deprecated
public JTextArea getOutput(){
return output;
}
public String append(String s){
output.append(s+"\n");
return s+"\n";
}
public String toString(){
return username;
}
public static void main(String[] args){
new ChatClientRMI(args[0]).go(args[1]);
}
class EnterListener implements ActionListener{
public void actionPerformed(ActionEvent ae){
try{
if (list.getSelectedValuesList().size() < 1){ // assume that they were too lazy and expect the program to do it for them
remote.sendToAll(ChatClientRMI.this, input.getText());
}else{ // send it to only the selected clients
remote.sendTo(ChatClientRMI.this, input.getText(), list.getSelectedValuesList());
}
}catch(NullPointerException ex){
System.out.println("Null pointer:");
ex.printStackTrace();
System.out.println("Caused by:");
ex.getCause().printStackTrace();
/*}catch(RemoteException ex){
System.out.println("Remote exception:");
ex.printStackTrace();*/
}catch(Exception ex){
ex.printStackTrace();
}
}
}
class HostListener implements ActionListener{
public void actionPerformed(ActionEvent ae){
Thread t = new Thread(new Runnable(){
public void run(){
ChatServerRMI.main(null);
}
});
t.start();
}
}
class ConnectListener implements ActionListener{
public void actionPerformed(ActionEvent ae){
frame.setVisible(false);
ChatClientRMI.this.go(JOptionPane.showInputDialog(frame, "Server IP:"));
}
}
}
My remote interface:
package server;
import java.rmi.*;
import java.util.*;
import client.*;
public interface ChatRemote extends Remote{
public void add(ChatClientRMI client) throws RemoteException;
public ArrayList<ChatClientRMI> getClients() throws RemoteException;
public void sendTo(ChatClientRMI from, String msg, List<ChatClientRMI> to) throws RemoteException;
public void sendToAll(ChatClientRMI from, String msg) throws RemoteException;
public void registerMe(ChatClientRMI me) throws RemoteException;
}
Please help! This is very frustrating. If you need more details, please inform me.
EDIT
I have even replaced my main method with
public static void main(String[] args){
ChatClientRMI chatClient = new ChatClientRMI(args[0]);
chatClient.go(args[1]);
chatClient.append("HI");
}
It does NOT throw a null pointer exception and outputs "HI" into the JTextArea, but when I click the button to send a message, triggering the 'sendToAll()' method, it throws the same null pointer exception as mentioned above.