JAVA: RMI Callback -> object already exported

2019-06-09 18:08发布

问题:

this is my first question, so sorry if i'll make it incorrect and for my english.

I have to do a distributed-hangman project in java, there are guests, players and masters (more matches). When a user(already registered) log himself or when a master open a match, the server must notifies to all guests (only guests) the event. In the client i had to create 2 stub, 1 for the server, the other one for the graphic interface (swing).

The threadpool is for manage the matches, not used now. This is the client code:

package User;

public class Utente extends RemoteServer implements UserInterface, GraphicInterface,Serializable {

private static final long serialVersionUID = 2L;
private String name;
private String password;
private String host = "localhost";
private Socket soc;
private int port = 1800;
private UserInterface stub = null;
private RegistryInterface server_interface = null;
private Registry server_registry;


public Utente(){
    super();
    this.name = "user";
    this.password = "passwd";
    //per connettersi al server
    try {
        server_registry = LocateRegistry.getRegistry(host);
        server_interface = (RegistryInterface)server_registry.lookup("HANGMAN-SERVER");
    } catch (RemoteException | NotBoundException e) {
        System.out.println("errore connessione lato client");
        e.printStackTrace();
    }
    //per l' rmi con la gui

}


public synchronized boolean login(String n, String p) throws RemoteException {
    boolean esito = false;
    export();
    esito = server_interface.login(n,p,stub);
    return esito;
}

public synchronized boolean logout() throws RemoteException {
    boolean esito = false;
    esito = server_interface.logout(name,stub);
    return esito;
}

public synchronized void notifyMatch(ArrayList<Partita> lista_partite) throws RemoteException {
    if(lista_partite!=null){
        if(lista_partite.size()==0){
            System.out.println("Ancora nessuna partita aperta.");
        }
        else{
            for(int i = 0;i<lista_partite.size();i++){
            System.out.println(lista_partite.get(i).getNameMatch());
            }
        }
    }
}

public void connect(){
    try {
        soc = new Socket(host, port);
    } catch (UnknownHostException e1) {
        e1.printStackTrace();
    } catch (IOException e1) {
        e1.printStackTrace();
    }

}


public static void main(String[] args) {
    Utente user = new Utente();
    Registry c;
    GraphicInterface stubExport = null;
    try{
        stubExport = (GraphicInterface)UnicastRemoteObject.exportObject(user,3900);
        LocateRegistry.createRegistry(5000);
        c=LocateRegistry.getRegistry();
        c.rebind("GraphicUI", stubExport);
    }
    catch (RemoteException e) {
        System.out.println("errore nel client: " + e.toString());
    }
    MainPanel startPanel = new MainPanel();
    startPanel.setVisible(true);    
}



}

Errors list:

UI export problems
java.rmi.server.ExportException: object already exported
    at sun.rmi.transport.ObjectTable.putTarget(Unknown Source)
    at sun.rmi.transport.Transport.exportObject(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport.exportObject(Unknown Source)
    at sun.rmi.transport.tcp.TCPEndpoint.exportObject(Unknown Source)
    at sun.rmi.transport.LiveRef.exportObject(Unknown Source)
    at sun.rmi.server.UnicastServerRef.exportObject(Unknown Source)
    at java.rmi.server.UnicastRemoteObject.exportObject(Unknown Source)
    at java.rmi.server.UnicastRemoteObject.exportObject(Unknown Source)
    at User.Utente.export(Utente.java:59)
    at User.Utente.login(Utente.java:100)
    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)
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$254(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$1/1989325584.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at registry.Server.callbackClient(Server.java:189)
    at registry.Server.login(Server.java:201)
    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)
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$254(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$1/1786588690.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
    at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
    at sun.rmi.server.UnicastRef.invoke(Unknown Source)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
    at com.sun.proxy.$Proxy0.login(Unknown Source)
    at User.Utente.login(Utente.java:101)
    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)
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$254(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$1/1989325584.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
    at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
    at sun.rmi.server.UnicastRef.invoke(Unknown Source)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
    at com.sun.proxy.$Proxy1.login(Unknown Source)
    at gui.MainPanel$2.actionPerformed(MainPanel.java:110)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

Thank you for your patience, i hope the question is well formed. The code is ugly i know, not much time and i changed it a lot.

回答1:

Probably, I guess I have found the error in your Utente class. You have exported your object at 2 places in your code, which results in java.rmi.server.ExportException:object already exported.

In your Utente's main() method, you have

stubExport = (GraphicInterface)UnicastRemoteObject.exportObject(user,3900);

where user is an object of class Utente.

Also, in the same class' login() method, you are calling export() method, which contains :-

stub = (UserInterface) UnicastRemoteObject.exportObject(this,0);

Here, this would pertain to Utente's currently calling object, which would be user in that case, which has already been exported earlier.

Hence, it seems you're exporting the object twice, resulting in the thrown exception.

Please reply whether this helped or not. Good Luck!