-1

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.

user2483722
  • 7
  • 1
  • 4
  • My suspicion is that it has to do with your registration method not doing what you think it is. Your client implements `Serializable`, so will be copied and sent to the remote server. Invocations on that deserialized object on the server will not reach the client on your machine. Also, you shouldn't need `rmic` -- that hasn't been required since Java 1.3, I believe. – Thorn G Jul 10 '13 at 20:26

2 Answers2

2
java.lang.NullPointerException
    at client.ChatClientRMI.append(ChatClientRMI.java:76)

You are dereferencing a null reference at line 76 of your ChatClientRMI class. Surely you can find like 76 in your own code? This problem has nothing to do with RMI whatsoever, and you won't find any websites that will contain solutions to java.lang.NullPointerException at client.ChatClientRMI.append(ChatClientRMI.java:76) either. You're really expected to be able to debug your own NPEs.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I know that it is a null reference. I just don't know what is causing it because I have initialized everything beforehand. I also know how to debug this. I've tried debugging it like 20 times w/ no luck, like I said. I have made a no-RMI version of this and it works perfectly. So I know that it has to do w/ RMI. – user2483722 Jun 14 '13 at 16:55
  • And heck, while you're at criticizing me, why don't you try to at least provide a decent answer rather than just stating the obvious. – user2483722 Jun 14 '13 at 23:56
  • 1
    If you know how to debug it, why *don't* you debug it, instead of shooting the messenger? It's only a short method. There is only one possibilty really. – user207421 Oct 02 '17 at 22:08
1

Your problem is that in this code

public String append(String s){
    output.append(s+"\n");
    return s+"\n";
}

You are calling append on output when output is null. The only reason I can think of for this is you calling your append method before calling your go method. Good luck.

Jurgen Camilleri
  • 3,559
  • 20
  • 45
  • In my main method, where it expects the username and IP address to connect to, it calls the 'go()' method, which initializes the variable 'output', so I don't think the JTextArea 'output' would be null, unless RMI is skipping over that. Thanks for trying, though. – user2483722 Jun 14 '13 at 19:08