无法从RMI服务器向客户端发送(服务)对象

时间:2017-07-19 11:01:57

标签: java rmi rmiregistry

我一直在试图找出问题,但我很确定服务器连接已经整齐地建立了。我甚至放了一些系统打印来确保发送和接收对象。让我先发布我的代码。

RemoteService.java(接口):

package testrmi;

import java.rmi.*;
import javax.swing.JPanel;

public interface RemoteService extends Remote {

    public Object[] getServiceList() throws RemoteException;
    public Service getService(Object SvcKey) throws RemoteException;

}

服务器提供的服务使用的Service.java(接口):

package testrmi;

import javax.swing.*;
import java.io.*;
import java.rmi.Remote;

public interface Service extends Serializable {

    public JPanel getGuiPanel();

}

RSimpl.java(RemoteService接口实现者)

package testrmi;
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;

public class RSimpl implements RemoteService {

    HashMap<String, Service> map;

    public RSimpl() throws RemoteException
    {
        //super();
        setUpServices();
    }

    public void setUpServices()
    {
        map = new HashMap<String, Service>();
        map.put("Dice Roll Service", new DiceRoll());
        map.put("Calculator Service", new Calculator());
        map.put("Clock Service", new DigitalClock1());
        // Keep Adding Services On The Go!
    }

    public Object[] getServiceList()
    {
        return map.keySet().toArray();
    }

    public Service getService(Object SvcKey)
    {
        System.out.println(SvcKey + " request has been recieved");
        Service theService = map.get(SvcKey);
        return theService;
    }
}

Client.java(客户端,看起来很脏:p)

package testrmi;

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

public class Client {

    JFrame frame;
    JPanel mainPanel;
    JComboBox<Object> comboBox;
    RemoteService server;
    int i = 0;
    Object[] error = {"Cannot Load Services"};

    public void buildGUI()
    {
        frame = new JFrame("Service Browser");
        mainPanel = new JPanel();

        attemptConnect();

        frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
        frame.getContentPane().add(BorderLayout.NORTH, comboBox);
        frame.setVisible(true);
        frame.setSize(300, 150);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        //centerFrame();
    }

    public void attemptConnect()
    {
        if(i==0)
        {
            i++;
            Object[] services = getServiceList();
            try {
                comboBox = new JComboBox<Object>(services);
                if (!services.toString().equalsIgnoreCase("Cannot Load Services"))
                comboBox.addActionListener(new MyListListener());
            }
            catch(Exception ex) {
                System.out.println("Cannot Establish Connection");
            }
        }
    }

    public void centerFrame()
    {
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (int) (d.getWidth()-frame.getWidth() / 2);
        int y = (int) (d.getHeight()-frame.getHeight() / 2);
        frame.setLocation(x, y);
    }

    public Object[] getServiceList()
    {
        boolean connectionsuccess = false;
        Object[] objList = null;
        try {
            Registry rs = LocateRegistry.getRegistry("127.0.0.1", 9797); //CHANGE TO 192.168.1.97
            server = (RemoteService) rs.lookup("RService");
            connectionsuccess = true;
        }
        catch(Exception ex) {
            Object[] options = {"Retry","Cancel"};
            int o = JOptionPane.showOptionDialog(frame, "Cannot Establish Connection To The Server. \n Do You Want To Retry?", "Connection Error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options, options[0]);
            if(o==0)
            {
                i=0;
                attemptConnect();
            }
            else
            {
                i=1;
                return error;
            }
        }
        if(connectionsuccess) {
            try {
                objList = server.getServiceList();
            }
            catch(Exception ex) {
                Object[] options = {"Retry","Cancel"};
                int o = JOptionPane.showOptionDialog(frame, "Cannot Fetch Services List From The Server. \n Do You Want To Retry?", "Fetch Error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options, options[0]);
                if(o==0)
                {
                    i=0;
                    attemptConnect();
                }
                else
                {
                    i=1;
                    return error;
                }
            }
        }
        return objList;
    }

    public void loadService(Object SvcKey)
    {
        try {
            System.out.println(" I am going to send key: " + SvcKey);
            Service svc = (Service) server.getService(SvcKey); //THIS IS CAUSING THE ERROR!
            System.out.println("i am yet working"); //THIS LINE IS NOT WORKING
            mainPanel.removeAll();
            //frame.setContentPane(svc.getGuiPanel());
            mainPanel.add(svc.getGuiPanel());
            mainPanel.validate();
            mainPanel.repaint();
            frame.pack();
            frame.setMinimumSize(new Dimension(300,150));
        }
        catch(Exception ex) {
            Object[] options = {"Retry","Cancel"};
            int o = JOptionPane.showOptionDialog(frame, "Cannot Load The Service From The Server. \n Do You Want To Retry?", "Connection Error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options, options[0]);
            if(o==0)
            {
                new MyListListener();
            }
            else
            {
                i=1;
                frame.repaint();
            }
        }
    }

    public class MyListListener implements ActionListener
    {
        public void actionPerformed(ActionEvent ev)
        {
            Object selection = comboBox.getSelectedItem();
            System.out.println(comboBox.getSelectedItem()); //DO NOT FORGET TO TEST THIS!
            loadService(selection);
        }
    }

    public static void main(String[] args)
    {
        Client cl = new Client();
        cl.buildGUI();
    }
}

StartServer.java(实例化RSimpl对象并启动服务器)

package testrmi;

import java.net.InetAddress;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class StartServer {

    public static void main(String[] args)
    {
        try {
            RSimpl obj = new RSimpl();
            RemoteService stub = (RemoteService) UnicastRemoteObject.exportObject(obj, 0);
            System.setProperty("java.rmi.server.hostname","192.168.1.97");
            //RemoteService rs = new RSimpl();
            Registry r = LocateRegistry.getRegistry(9797);
            r.rebind("RService", stub);
            System.out.println("Remote Service Is Running");
            System.out.println(""+ InetAddress.getLocalHost().getHostAddress());
        }
        catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Sorry, Cannot Start Remote Service");
        }
    }   

}

Calculator.java(计算器服务,无需检查)

package testrmi;

import javax.script.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;

public class Calculator implements Service, Serializable {

    JPanel mainPanel;

    public JPanel getGuiPanel()
    {
        mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());

        //JPanel p1 = new JPanel();
        //p1.setLayout(new GridLayout(4,4));

        JPanel p1 = new JPanel();
        JPanel p2 = new JPanel();
        JPanel p3 = new JPanel();
        JPanel p4 = new JPanel();

        final JTextField t = new JTextField(10);
        t.setEditable(false);
        t.setBackground(Color.green);
        t.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        Font myFont = new Font("MS Sans Serif", Font.BOLD, 24);
        t.setFont(myFont);

        mainPanel.add(t,BorderLayout.NORTH);

        final JButton n1 =  new JButton("1");
        n1.setFocusable(false);
        n1.setFont(myFont);
        n1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n1.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);
            }
        });

        final JButton  n2 =  new JButton("2");
        n2.setFocusable(false);
        n2.setFont(myFont);
        n2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n2.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);    
            }
        });

        final JButton  n3 =  new JButton("3");
        n3.setFocusable(false);
        n3.setFont(myFont);
        n3.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n3.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);
            }
        });

        final JButton  n4 =  new JButton("4");
        n4.setFocusable(false);
        n4.setFont(myFont);
        n4.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n4.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);
            }
        });

        final JButton  n5 =  new JButton("5");
        n5.setFocusable(false);
        n5.setFont(myFont);
        n5.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n5.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global); 
            }
        });

        final JButton  n6 =  new JButton("6");
        n6.setFocusable(false);
        n6.setFont(myFont);
        n6.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n6.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);
            }
        });

        final JButton  n7 =  new JButton("7");
        n7.setFocusable(false);
        n7.setFont(myFont);
        n7.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n7.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);  
            }
        }); 

        final JButton  n8 =  new JButton("8");
        n8.setFocusable(false);
        n8.setFont(myFont);
        n8.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n8.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);  
            }
        }); 

        final JButton  n9 =  new JButton("9");
        n9.setFocusable(false);
        n9.setFont(myFont);
        n9.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n9.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);  
            }
        });


        final JButton  n10 =  new JButton("0");
        n10.setFocusable(false);
        n10.setFont(myFont);
        n10.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n10.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);
            }
        });

        final JButton  n11 =  new JButton("+");
        n11.setFocusable(false);
        n11.setFont(myFont);
        n11.setForeground(Color.MAGENTA);
        n11.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n11.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);  
            }   
        });


        final JButton  n12 =  new JButton("-");
        n12.setFocusable(false);
        n12.setFont(myFont);
        n12.setForeground(Color.MAGENTA);
        n12.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n12.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global); 
            }
        });

        final JButton  n13 =  new JButton("*");
        n13.setFocusable(false);
        n13.setFont(myFont);
        n13.setForeground(Color.MAGENTA);
        n13.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n13.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global); 
            }           
        });

        final  JButton  n14 =  new JButton("/");
        n14.setFocusable(false);
        n14.setFont(myFont);
        n14.setForeground(Color.MAGENTA);
        n14.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                String num1 = n14.getText();
                String global = t.getText();
                global = global.concat(num1);
                t.setText(global);  
            }
        });

        final JButton  n15 =  new JButton("=");
        n15.setFocusable(false);
        n15.setFont(myFont);
        n15.setForeground(Color.BLUE);
        n15.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                //String num1 = n15.getText();
                String global = t.getText();
                //global = global.concat(num1);

                ScriptEngineManager mgr = new ScriptEngineManager();
                ScriptEngine engine = mgr.getEngineByName("JavaScript");
                try {
                    String s = engine.eval(global).toString();
                    t.setText(s); 
                } 
                catch (ScriptException e1) {
                    e1.printStackTrace();
                }  
            }
        });

        final  JButton  n16 =  new JButton("C");
        n16.setFocusable(false);
        n16.setFont(myFont);
        n16.setForeground(Color.RED);
        n16.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                //String num1 = n16.getText();
                String global = t.getText();
                global = null;
                t.setText(global);
            }
        });

        p1.add(n1);
        p1.add(n2);
        p1.add(n3);
        p1.add(n4);
        p2.add(n5);
        p2.add(n6);
        p2.add(n7);
        p2.add(n8);
        p3.add(n9);
        p3.add(n10);
        p3.add(n11);
        p3.add(n12);
        p4.add(n13);
        p4.add(n14);
        p4.add(n15);
        p4.add(n16);

        JPanel pPanel = new JPanel();
        pPanel.setLayout(new BoxLayout(pPanel, BoxLayout.Y_AXIS));
        pPanel.add(p1);
        pPanel.add(p2);
        pPanel.add(p3);
        pPanel.add(p4);

        mainPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
        mainPanel.add(pPanel);
        return mainPanel;
    }
}

DiceRoll.java(DiceRoll服务,无需检查)

package testrmi;

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

public class DiceRoll implements Service {

    int i = 0;
    int h = 0;
    JPanel mainPanel;
    JButton roll;
    MyDrawPanel drawPanel;

    public JPanel getGuiPanel()
    {
        mainPanel = new JPanel();
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));

        roll = new JButton("Roll The Dice!");
        roll.setFont(new Font("Comic Sans Ms", Font.BOLD, 16));
        roll.setFocusable(false);
        roll.setAlignmentX(Component.CENTER_ALIGNMENT);
        roll.addActionListener(new rollListener());

        drawPanel = new MyDrawPanel();
        drawPanel.setPreferredSize(new Dimension(150,150));

        mainPanel.add(roll);
        mainPanel.add(Box.createRigidArea(new Dimension(0,10)));
        mainPanel.add(drawPanel);
        mainPanel.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
        return mainPanel;
    }

    public int roll()
    {
        while (i==0 || i==h)
        {
            i = (int) (Math.random()*7);
        }
        h = i;
        return i;
    }

    public class rollListener implements ActionListener
    {
        public void actionPerformed(ActionEvent ev)
        {
            int x = roll();
            drawPanel.sendNum(x);
            drawPanel.repaint();
        }
    }

    public class MyDrawPanel extends JPanel
    {
        Graphics g;
        int least = 0, x;
        int fx=0, fy=0, fw=150, fh=150;
        int dw=100, dh=100;
        int dx=((fw-dw)/2), dy=((fh-dh)/2);
        int dxc,dyc,dx1,dy1,dx2,dy2,dx3,dy3,dx4,dy4,dx5,dy5,dx6,dy6;

        public void paintComponent(Graphics gn)
        {
            g = gn;
            super.paintComponent(g);
            g.setColor(Color.LIGHT_GRAY);
            g.fillRect(fx, fy, fw, fh);
            g.setColor(Color.WHITE);
            g.fillRoundRect(dx, dy, dw, dh, 30, 30);
            g.setColor(Color.BLACK); // set black for dots and border
            g.drawRoundRect(dx, dy, dw, dh, 30, 30);
            if(least>=1)
            {
                if(x==1)
                {
                    g.fillOval(dxc, dyc, 20, 20);
                }
                else if(x==2)
                {
                    g.fillOval(dx1, dy1, 20, 20);
                    g.fillOval(dx6, dy6, 20, 20);
                }
                else if(x==3)
                {
                    g.fillOval(dx1, dy1, 20, 20);
                    g.fillOval(dxc, dyc, 20, 20);
                    g.fillOval(dx6, dy6, 20, 20);
                }
                else if(x==4)
                {
                    g.fillOval(dx1, dy1, 20, 20);
                    g.fillOval(dx2, dy2, 20, 20);
                    g.fillOval(dx5, dy5, 20, 20);
                    g.fillOval(dx6, dy6, 20, 20);
                }
                else if(x==5)
                {
                    g.fillOval(dx1, dy1, 20, 20);
                    g.fillOval(dx2, dy2, 20, 20);
                    g.fillOval(dxc, dyc, 20, 20);
                    g.fillOval(dx5, dy5, 20, 20);
                    g.fillOval(dx6, dy6, 20, 20);
                }
                else if(x==6)
                {
                    g.fillOval(dx1, dy1, 20, 20);
                    g.fillOval(dx2, dy2, 20, 20);
                    g.fillOval(dx3, dy3, 20, 20);
                    g.fillOval(dx4, dy4, 20, 20);
                    g.fillOval(dx5, dy5, 20, 20);
                    g.fillOval(dx6, dy6, 20, 20);
                }
            }
        }

        public void sendNum(int xx)
        {
            least = 1;
            x = xx;
            // REMEMBER: dx+40=CENTER_X and dy+40=CENTER_Y because dice size 100, dot size 20
            dxc=dx+40;
            dyc=dy+40;
            dx1=dx+10;
            dy1=dy+10;
            dx2=dx+70;
            dy2=dy+10;
            dx3=dx+10;
            dy3=dy+40;
            dx4=dx+70;
            dy4=dy+40;
            dx5=dx+10;
            dy5=dy+70;
            dx6=dx+70;
            dy6=dy+70;
        }
    } // close class MyDrawPanel
}

DigitalClock1.java(无需检查 - 这些仅用于编译目的)

package testrmi;

import java.awt.*; 
import java.util.*;
import javax.swing.*;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.awt.event.ActionEvent;

public class DigitalClock1 implements Service
{
        public JPanel getGuiPanel()
        {
            SimpleDigitalClock clock1 = new SimpleDigitalClock();
            return clock1;
        }
        static class SimpleDigitalClock extends JPanel
        { 
            String stringTime;
            int hour, minute, second;
            String aHour = "";
            String bMinute = "";
            String cSecond = ""; 
            public void setStringTime(String abc)
            {
                this.stringTime = abc;
            } 
            public int Number(int a, int b)
            {
                return (a <= b) ? a : b;
            } 
            SimpleDigitalClock()
            { 
                Timer t = new Timer(1000, new ActionListener()
                { 
                    public void actionPerformed(ActionEvent e)
                    {
                        repaint();
                    }
                });
                t.start();
            }
            @Override 
            public void paintComponent(Graphics v)
            {
                super.paintComponent(v);
                Calendar rite = Calendar.getInstance();
                hour = rite.get(Calendar.HOUR_OF_DAY);
                minute = rite.get(Calendar.MINUTE);
                second = rite.get(Calendar.SECOND);
                if (hour < 10)
                {
                    this.aHour = "0"; 
                } 
                if (hour >= 10)
                {
                    this.aHour = "";
                } 
                if (minute < 10)
                {
                    this.bMinute = "0";
                } 
                if (minute >= 10)
                {
                    this.bMinute = "";
                }
                if (second < 10)
                {
                    this.cSecond = "0";
                }
                if (second >= 10)
                {
                    this.cSecond = "";
                } 
                setStringTime(aHour + hour + ":" + bMinute+ minute + ":" + cSecond + second);
                v.setColor(Color.BLACK);
                int length = Number(this.getWidth(),this.getHeight());
                Font Font1 = new Font("Comic Sans MS", Font.PLAIN, length / 5);
                v.setFont(Font1);
                v.drawString(stringTime, (int) length/6, length/2);
            } 
            @Override 
            public Dimension getPreferredSize()
            {
                return new Dimension(200, 200);
            }
        }
}

我从同时放置start rmiregistry 9797目录(包)的目录中运行testrmi。然后我从同一目录运行java testrmi.StartServer。我得到服务器正在运行的消息,然后我从另一个目录运行客户端但具有相同的包名,其中只包含Client.class,RemoteService.class和Service.class;客户端启动正常,显示所有三个服务,但是当我从列表中选择时,我收到异常错误“无法加载服务,重试?”。

注意:如果我在客户端软件包目录中复制服务(calculator.class,diceroll.class和digitalclock1.class),客户端将正确加载服务。我不希望在没有连接到服务器的情况下直接访问客户端的服务。

1 个答案:

答案 0 :(得分:1)

如果您希望能够将可序列化对象返回到不在客户端类路径中的客户端,则需要使用RMI codebase feature,其中需要您部署代码库服务器,并使用客户端SecurityManager