-1

抱歉,如果这是一个“duh”问题,这是我第一次在 Stack Overflow 上。我的问题是,我的代码中不断出现空指针异常,我不知道如何修复它。

    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)
        ...

我的代码设计如下:我的服务器跟踪连接到它的客户端,我的客户端可以通过使用 RMI 调用方法“sendToAll()”向所有其他客户端发送消息,该方法将该消息附加到所有客户端的 JTextAreas。如果您想知道,我一直在运行 RMI Registry,并且我已经从 Java JDK 附带的 rmic 工具中获得了存根。如果这很重要,我在 Windows XP 上使用带有命令提示符的 Notepad++。我也在许多网站上对此进行了研究,但没有找到答案。我的服务器代码如下:

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

我的客户代码在这里:

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

我的远程界面:

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

请帮忙!这非常令人沮丧。如果您需要更多详细信息,请通知我。

编辑

我什至用我的主要方法替换了

public static void main(String[] args){
     ChatClientRMI chatClient = new ChatClientRMI(args[0]);
     chatClient.go(args[1]);
     chatClient.append("HI");
}

它不会抛出空指针异常并将“HI”输出到 JTextArea,但是当我单击按钮发送消息,触发“sendToAll()”方法时,它会抛出与上述相同的空指针异常。

4

2 回答 2

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

您在 ChatClientRMI 类的第 76 行取消引用空引用。您肯定可以在自己的代码中找到类似 76 的内容吗?这个问题与 RMI 无关,您也找不到任何包含解决方案的网站java.lang.NullPointerException at client.ChatClientRMI.append(ChatClientRMI.java:76)。您确实希望能够调试自己的 NPE。

于 2013-06-14T07:51:01.407 回答
1

你的问题是在这段代码中

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

您正在调用append时为空outputoutput我能想到的唯一原因是你在调用你的append方法之前调用你的go方法。祝你好运。

于 2013-06-14T07:57:37.277 回答