无法将RMI客户端连接到主机,由eofexception引起的unmarshalexception

时间:2013-10-06 22:00:27

标签: java exception rmi eofexception

我在netbeans中打开了以下文件。

服务器:

package server;

import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.sql.*;

public class Server implements ServerInterface {

    private Connection con;
    private Statement st;

    public Server(String db, String username, String password) {
        try {
            con = DriverManager.getConnection(db, username, password);
            st = con.createStatement();
        } catch(Exception e) {
            System.out.println(e);
        }
    }

    public static void main(String[] args) {
        try {
            Server server = new Server("jdbc:mysql://localhost:3306/db", "root", "password");
            System.setSecurityManager(new RMISecurityManager());
            ServerInterface stub = (ServerInterface) UnicastRemoteObject.exportObject(server, 0);
            Registry registry = LocateRegistry.createRegistry(1099);
            registry.rebind("Server", stub);
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public boolean authenticate(String username, String password) {
        try {
            String query = "SELECT * FROM staff WHERE staff_id ='" + username + "' AND password = '" + password + "'";
            ResultSet rs = st.executeQuery(query);
            if(rs.next()) {
                return true;
            } else {
                return false;
            }
        } catch(Exception e) {
            System.out.println(e);
        }
        return false;
    }
}

客户端:

package client;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.rmi.registry.*;

public class Client extends JFrame implements ActionListener {

    JFrame main;
    JPanel loginPanel;
    JPanel contentPanel;
    JButton horse;
    JButton staff;
    JButton loan;
    JButton treatment_record;
    JButton work_record;
    JButton contact;
    JButton loaner;
    JButton field_visit;
    JButton login;
    JTextField username;
    JPasswordField password;
    String usernameString;
    String passwordString;

    public Client() {

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            System.out.println(e);
        }

        loginPanel = new JPanel();
        contentPanel = new JPanel();
        login = new JButton("Login");
        username = new JTextField(20);
        password = new JPasswordField(20);
        horse = new JButton("Horses");
        staff = new JButton("Staff");
        loan = new JButton("Current Loans");
        treatment_record = new JButton("Treatment Records");
        work_record = new JButton("Work Records");
        contact = new JButton("Contacts");
        loaner = new JButton("Loaners");
        field_visit = new JButton("Field Visits");

        horse.addActionListener(this);
        staff.addActionListener(this);
        loan.addActionListener(this);
        treatment_record.addActionListener(this);
        work_record.addActionListener(this);
        contact.addActionListener(this);
        loaner.addActionListener(this);
        field_visit.addActionListener(this);
        login.addActionListener(this);

        loginPanel.add(new JLabel("Username"));
        loginPanel.add(username);
        loginPanel.add(new JLabel("Password"));
        loginPanel.add(password);
        loginPanel.add(login);
        contentPanel.add(horse);
        contentPanel.add(staff);
        contentPanel.add(loan);
        contentPanel.add(treatment_record);
        contentPanel.add(work_record);
        contentPanel.add(contact);
        contentPanel.add(loaner);
        contentPanel.add(field_visit);
        contentPanel.setLayout(new GridLayout(0, 3));
        loginPanel.setLayout(new GridLayout(0, 2));
        contentPanel.setSize(800, 600);

        this.setTitle("TRC Database");
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setContentPane(loginPanel);
        this.setVisible(true);   
        this.pack();
    }

    public static void main(String[] args) {
        new Client();

        try {
            Registry registry = LocateRegistry.getRegistry();
            ServerInterface stub = (ServerInterface) registry.lookup("Server");
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public void actionPerformed(ActionEvent ae) {
        if (ae.getSource() == login) {
            usernameString = username.getText();
            passwordString = password.getText();
            JOptionPane.showMessageDialog(null, "Button pressed!");
        }
        this.revalidate();
        this.pack();
    }
}

客户端存根:

package client;

import java.rmi.*;

public interface ServerInterface extends Remote {
    public boolean authenticate(String username, String password) throws RemoteException;
}

服务器端存根:

package server;

import java.rmi.*;

public interface ServerInterface extends Remote {
    public boolean authenticate(String username, String password) throws RemoteException;
}

服务器类执行正常,但运行客户端类会出现以下错误:

java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: 
    java.io.EOFException

堆栈跟踪:

java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: 
    java.io.EOFException
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:227)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at client.Client.main(Client.java:88)
Caused by: java.io.EOFException
    at java.io.DataInputStream.readByte(DataInputStream.java:267)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:213)
    ... 3 more

我见过很多人都有相同的错误消息,但我找不到任何解决方案。有人可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

这通常是由对等方的沙箱权限问题引起的。摆脱安全经理。你在这里不需要它。

答案 1 :(得分:0)

另一个原因可能是您要传输的对象不是真正可序列化的。不幸的是,服务器RMI默认情况下不记录此内容。在返回对象之前,检查此问题的最佳方法是在服务器端:

  try {
     new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(object);
  } catch (Exception e) {
     logger.error("serializable check failed", e);
  }