2017-07-19 129 views
-2

我一直在試圖找出問題,我非常肯定服務器連接建立整齊地殺死我的大腦。我甚至放了一些系統打印件以確保對象被髮送和接收。讓我先發布我的代碼。無法發送(服務)對象從RMI服務器到客戶端

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

我從其中testrmi目錄(包)也放在該目錄運行start rmiregistry 9797。然後我從同一個目錄運行java testrmi.StartServer。我得到的服務器正在運行的消息,然後我從另一個目錄運行客戶端,但具有相同的包名稱,它只包含Client.class,RemoteService.class和Service.class;客戶端啓動正常,顯示所有三個服務,但是當我從列表中選擇時,出現異常錯誤'無法加載服務,重試?'。

注:如果我複製客戶端軟件包目錄中的服務(calculator.class,diceroll.class和digitalclock1.class),則客戶端會正確加載服務。我不希望服務在沒有連接到服務器的情況下直接被客戶訪問。

+0

''無法加載服務,重試?'不是Java錯誤消息或異常。這大概是你自己設計的一些錯誤信息,並沒有傳達任何有用的信息,而這是你沒有在這裏發佈的代碼顯示的。請在您的問題中提供實際的異常和堆棧跟蹤,並且請從您的問題中刪除大約880碼毫無意義且不相關的Swing代碼。 – EJP

+0

多數民衆贊成說,我說,異常被捕獲,並顯示我設置它! :( 錯誤發生在'Client.java'中 請在方法'loadService(Object SvcKey)'處查看client.java,並閱讀我的評論。我不知道我能清楚多少:/ – Hanzyusuf

+0

什麼例外?什麼是堆棧跟蹤?我要求的任何東西在哪裏? – EJP

回答

1

如果你想能夠序列化對象返回給客戶端不在客戶端的類路徑中,你需要使用RMI codebase feature,除其他事情需要你部署代碼庫服務器,並在使用SecurityManager客戶端。

+0

thnx我一定會試試這個,不知道。並儘量讓人們更好;) – Hanzyusuf

+0

兄弟有沒有其他方式可以做到這一點?我記得我的「頭一個java」書有rmi解釋,但它不包含用於動態類下載的代碼庫,服務被自動序列化併發送到客戶端。 – Hanzyusuf

相關問題