Avatar billede peterfup Nybegynder
13. marts 2002 - 16:58 Der er 5 kommentarer og
1 løsning

Observer pattern over RMI

Jeg har et problem med observer over RMI.
Jeg har lavet et eksempel hvor man starter serveren, binder serveren så den er tilgængelig for klienterne.
Når en client starter programmet, registrerer den sig på serveren for at modtage opdateringer om en liste over personer.
Mit problem er at når jeg via en client tilføjer en person på serveren, kaldes der en notifyAllClients() som kalder update() på de tilmeldte clienter, men den kan ikke kalde tilbage til mine registrerede objekter og kaster en exception.
Mit eksempel er lavet på baggrund af kap. 24 i bogen: Java Network Programming (http://www.manning.com/Hughes/)

Er der nogen der kan komme med en forklaring på problemet eller evt. komme med et alternativt løsningsforslag?

Her er min kode (Der er ozze en kode for Person, men den er der ikke noget specielt ved - Skriv hvis du gerne vil se den):

SERVERINTERFACE------------------------------------------------------------------------>

import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import javax.swing.*;

public interface ServerIF extends Remote{

    public abstract void deregister(Client client) throws RemoteException;
    public abstract void addElement(PersonIF p) throws RemoteException;
    public abstract DefaultComboBoxModel register(ClientIF client) throws RemoteException;
    public abstract void createPerson(String n, int a) throws RemoteException;
    public abstract void notifyClients() throws RemoteException;
}

SERVERIMPLEMENTERING---------------------------------------------------------------------->

import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.util.*;
import javax.swing.*;

public class Server extends UnicastRemoteObject implements ServerIF{

    protected DefaultComboBoxModel liste;
    protected Vector clients;
   
    public Server() throws RemoteException {
        this.liste = new DefaultComboBoxModel();
        this.clients = new Vector();
    }

    public synchronized void addElement(PersonIF p) throws RemoteException {
        (this.liste).addElement(p);
        this.notifyClients();
    }

    public synchronized void deregister(Client client) {
        (this.clients).remove(client);
    }

    public static void main(String args[]) throws RemoteException, AlreadyBoundException { 
          try
              { 
                System.out.println("Constructing server implementations...");

                PersonIF p1 = new Person("Jesper", 10);
                    PersonIF p2 = new Person("Banke", 12);
 
                ServerIF serv = new Server();
 
                serv.addElement(p1);
                serv.addElement(p2);

                System.out.println("Starting up registry...!");

                Registry registry = LocateRegistry.getRegistry();

            System.out.println("Binding server implementations to registry...");

                Naming.bind("jesper", p1);
                Naming.bind("banke", p2);
                      registry.rebind("server", serv);
                 
                System.out.println("Waiting for invocations from clients...");
        }
              catch(Exception e)
              { 
                  System.out.println("Error: " + e);
              }
      }

    public synchronized DefaultComboBoxModel register(ClientIF client) {
        (this.clients).add(client);

        return this.liste;
    }

    public void createPerson(String n, int a) throws RemoteException {
        PersonIF pers = new Person(n, a);
        this.addElement(pers);
    }

    public synchronized void notifyClients() throws RemoteException
    {
        for(int i = 0; i < (this.clients).size(); i++)
        {               
            ( (Client) (this.clients).elementAt(i) ).update(this.liste);
        }
    }
}

CLIENTINTERFACE------------------------------------------------------------------------------------>

import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import javax.swing.*;

    public interface ClientIF extends Remote {
        public abstract void addElement(PersonIF p) throws RemoteException;
        public abstract void update(DefaultComboBoxModel v) throws RemoteException;
    }

CLIENTIMPLEMENTERING----------------------------------------------------------------------------------->

import javax.swing.*;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.util.*;


public class Client extends UnicastRemoteObject implements ClientIF {

    private DefaultComboBoxModel liste;
    protected ServerIF server;
   
    public Client() throws RemoteException, NotBoundException {
        server = new Server();
        liste = new DefaultComboBoxModel();
               
        System.setSecurityManager(new RMISecurityManager());
              String url = "10.40.2.70";
       
              try
              {
                  Registry registry = (Registry) LocateRegistry.getRegistry(url);//Naming.lookup("rmi://localhost/" + "registry");
               
                  server = (ServerIF) registry.lookup("server");
       
                  liste = server.register(this);

                  for(int i = 0; i < liste.getSize(); i++)
            {
                PersonIF tmp = (PersonIF) (liste.getElementAt(i));
                  System.out.println(tmp.getName());
            }
             
                GUI g;
                g = new GUI(this);
                     
            }
              catch(Exception e)
              { 
                  System.out.println("Error" + e);
              }
    }

    public synchronized void addElement(PersonIF p) throws RemoteException {
        server.addElement(p);
    }

    public DefaultComboBoxModel getListe() {
        return this.liste;
    }

    public synchronized void update(DefaultComboBoxModel v) throws RemoteException {
        this.liste = v;
    }

    public void createPerson(String n, int a) throws RemoteException {
        (this.server).createPerson(n, a);
    }

    public static void main(String[] args) throws RemoteException, NotBoundException {
        ClientIF client = new Client();
    }
}

GUIIMPLEMENTERING-------------------------------------------------------------------------------------->

import javax.swing.*;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.util.*;
import java.awt.*;
import javax.swing.JFrame;
import java.awt.List;
import java.awt.event.*;

public class GUI extends JFrame implements ActionListener
{
    private DefaultComboBoxModel liste;
    private Client client;
   
    private Button add, print, delete;
    private JPanel conPanel;
   
    public GUI(Client client)
    {
        this.client = client;
        this.liste = client.getListe();

        //Grænseflade-start
            this.setSize (500,400);
        this.setTitle ("Observer");
        this.setVisible(true);

        conPanel = new JPanel();
        this.setContentPane(conPanel);   
         
    //Knapper:
        add = new Button("Tilføj Person");
        add.setBounds(300, 50, 85, 25);
       
        print = new Button("Udskriv liste");
        print.setBounds(300, 100, 85, 25);

        delete = new Button("Slet Person");
        delete.setBounds(300, 150, 85, 25);

    //Tilføj ActionListeners
        add.addActionListener (this);
        print.addActionListener (this);
        delete.addActionListener (this);

        this.getContentPane().add(add);
        this.getContentPane().add(print);
        this.getContentPane().add(delete);

    }
   
    public void actionPerformed(ActionEvent ae)
      {
        try
        {
            if (ae.getSource ()== print {
                  for(int i = 0; i < (client.getListe()).getSize(); i++)
                  {
                      PersonIF tmp = (PersonIF) ((client.getListe()).getElementAt(i));
                      System.out.println(tmp.getName());
                  }
            }

              if (ae.getSource ()== add)
              {
                  (this.client).createPerson("Knud", 21);
              }

              if (ae.getSource ()== delete)
              {
                                   
              }
        }
        catch (Exception e) {
            System.out.println("Error: " + e);
        }
      }

    public synchronized void addElement(ServerIF server, Person p) throws RemoteException {
        (this.liste).addElement(p);
        server.addElement(p);
    }

    public synchronized void update(DefaultComboBoxModel v) throws RemoteException
    {
        this.liste = v;
    }
}




Avatar billede peterfup Nybegynder
13. marts 2002 - 17:10 #1
Jeg har selvfølgelig ozze oprettet stubbene for Client, Server og Person...
Avatar billede thomaz Nybegynder
13. marts 2002 - 17:19 #2
Hvad er det for en exception du får ??.
Avatar billede madshenrik Nybegynder
13. marts 2002 - 18:49 #3
har du ikke fundet en løsning endnu dit fedt øre
Avatar billede madshenrik Nybegynder
13. marts 2002 - 18:50 #4
Jeg regner selvfølgelig med at næste gang vi ses har du fundet en løsning
Avatar billede peterfup Nybegynder
14. marts 2002 - 12:05 #5
java.rmi.UnexpectedException: undeclared checked exception; nested exception is:
    java.lang.Exception: java.lang.ClassCastException
    java.lang.Throwable()
    java.lang.Exception()
    java.lang.RuntimeException()
    java.lang.ClassCastException()
    void docuflow.Server.notifyClients()
    void docuflow.Server.notifyClients()
    void docuflow.Server.addElement(docuflow.PersonIF)
    void docuflow.Server.createPerson(java.lang.String, int)
    java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object [])
    void sun.rmi.server.UnicastServerRef.dispatch(java.rmi.Remote, java.rmi.server.RemoteCall)
    java.lang.Object sun.rmi.transport.Transport$1.run()
    java.lang.Object java.security.AccessController.doPrivileged(java.security.PrivilegedExceptionAction, java.security.AccessControlContext)
    boolean sun.rmi.transport.Transport.serviceCall(java.rmi.server.RemoteCall)
    void sun.rmi.transport.tcp.TCPTransport.handleMessages(sun.rmi.transport.Connection, boolean)
    void sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run()
    void java.lang.Thread.run()
Avatar billede peterfup Nybegynder
14. marts 2002 - 12:51 #6
Jeg har selv fundet fejlen...
Det var til dels en dårlig netværksforbindelse, og så skulle der castes til ClientIF istedet for Client i metoden notifyAllClients() i ServerImplementeringen.
Nu kører alt fint!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester