抱歉,如果这是一个“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()”方法时,它会抛出与上述相同的空指针异常。