RMI Complicated Issues

219 views Asked by At

This is somewhat of a mess. I am getting an error when my remote object on the server tries to access other objects on the server. I think that what is happening is that the client is instantiating its own object of the remote implementation class, but I really know very little about this. Here's the error (I am really sorry about the assert message; I assumed no one else would read this):

Exception in thread "AWT-EventQueue-0" java.lang.AssertionError: WTF?
at com.eotg.WebInterface.GlobalNetIO.registerAccount(GlobalNetIO.java:123)
at com.eotg.Client.ClientIO.registerAccount(ClientIO.java:92)
at com.eotg.Client.GUI.actionPerformed(GUI.java:260)
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$200(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)

Note that this is on the client side even though GlobalNetIO is a server-side class.

Here's GlobalNetIO:

package com.eotg.WebInterface;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.ArrayList;

import com.eotg.Engine.Galaxy;
import com.eotg.UserSystem.User;
import com.eotg.Util.MathC;
import com.eotg.WebUtils.*;

public class GlobalNetIO implements EotGRemote, Serializable
{
    /**
     * 
     */
    private static final long serialVersionUID = 4316258945377312760L;
    public static final String DIR = "c:/Users/Josh/Dropbox/EotG/Eo_Nova_Server/";
    ArrayList<UserNetIO> m_UserInterfaces;

    public GlobalNetIO()
    {
        m_UserInterfaces = new ArrayList<UserNetIO>();
    }

    protected void handleNewClient()
    {

    }

    public static void ErrorMessage(boolean b, String sz)
    {
        if (b)
        {
            System.err.print(sz);
        }
    }

    public ArrayList<UserNetIO> getUserInterfaces()
    {
        return m_UserInterfaces;
    }

    public int getNumUserInterfaces()
    {
        return m_UserInterfaces.size();
    }

    public UserNetIO getUserInterface(int i)
    {
        assert i > -1 : "Invalid index.";
        assert i < getNumUserInterfaces() : "Invalid index.";
        return m_UserInterfaces.get(i);
    }

    public UserNetIO getUserInterface(String szID)
    {
        for (int i = 0; i < getNumUserInterfaces(); i++)
        {
            if (getUserInterface(i).getIDString().equals(szID))
                return getUserInterface(i);
        }
        return null;
    }

    private String makeIDString(int iNumChars)
    {
        char[] str = new char[iNumChars];
        for (int i = 0; i < iNumChars; i++)
        {
            str[i] = MathC.randomValidChar();
        }
        String sz = String.valueOf(str);
        for (int i = 0; i < getNumUserInterfaces(); i++)
        {
            if (sz.equals(getUserInterface(i).getIDString()))
            {
                sz = makeIDString(iNumChars);
            }
        }
        return sz;
    }

    @Override
    public String[] login(String szUsername, String szPassword) throws RemoteException 
    {
        String[] szPhrases;
        User u = Galaxy.World.getUserByName(szUsername);
        if (u == null)
        {
            szPhrases = new String[]{"0","Username is not valid."};
            return szPhrases;
        }

        if (!u.getPassword().equals(szPassword))
        {
            szPhrases = new String[]{"0","Username is valid but password is incorrect."};
            return szPhrases;
        }
        String sz = makeIDString(32);
        UserNetIO UsrIO = new UserNetIO(sz,u);
        getUserInterfaces().add(UsrIO);
        return new String[]{sz};
    }

    @Override
    public void logout(String szID) throws RemoteException 
    {
        for (int i = 0; i < getNumUserInterfaces(); i++)
        {
            if (getUserInterface(i).getIDString().equals(szID))
            {
                getUserInterfaces().remove(i);
                return;
            }
        }
    }

    @Override
    public String[] registerAccount(String szUsername, String szFirstName, String szLastName, String szEmail) throws RemoteException 
    {
        String[] szPhrases;
        assert Galaxy.World != null : "WTF?";
        if (Galaxy.World.getUserByName(szUsername) != null)
        {
            szPhrases = new String[]{"0","Register failed: That username is already in use."};
            return szPhrases;
        }
        if (Galaxy.World.getUserByEmail(szEmail) != null)
        {
            szPhrases = new String[]{"0","Register failed: An account is already registered with that email."};
            return szPhrases;
        }

        Galaxy.World.addUser(szUsername, szFirstName, szLastName, szEmail);
        szPhrases = new String[]{"1", "Register success! Your password is:" + Galaxy.World.getUser(Galaxy.World.getNumUsers()-1).getPassword()};
        return szPhrases;
    }

    @Override
    public String[] getUserAttribute(String szID, int iAttribute) throws RemoteException 
    {
        return getUserInterface(szID).getUserAttribute(iAttribute);
    }

    @Override
    public String[] tryChangeUserAttribute(String szID, int iAttribute, String szNewVal)
    {
        return getUserInterface(szID).tryChangeUserAttribute(iAttribute, szNewVal);
    }

    @Override
    public int getNumRaceInfos() throws RemoteException 
    {
        return Galaxy.World.getNumRaceInfos();
    }

    @Override
    public int getNumFactionInfos() throws RemoteException 
    {
        return Galaxy.World.getNumFactionInfos();
    }
}

Some relevant bits of Galaxy (Server-side):

package com.eotg.Engine;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.rmi.RMISecurityManager;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.List;

import JeXML.InfoBase;
import JeXML.JeTextMgr;
import JeXML.JeXMLInterface;

import com.eotg.AI.God;
import com.eotg.ConstantInfos.Element;
import com.eotg.ConstantInfos.FactionInfo;
import com.eotg.ConstantInfos.Molecule;
import com.eotg.ConstantInfos.PlanetType;
import com.eotg.ConstantInfos.PrefabSystem;
import com.eotg.ConstantInfos.RaceInfo;
import com.eotg.ConstantInfos.StarType;
import com.eotg.Game.GameObject;
import com.eotg.Game.Biology.Organism;
import com.eotg.UserSystem.DateTime;
import com.eotg.UserSystem.Player;
import com.eotg.UserSystem.User;
import com.eotg.Util.Point;
import com.eotg.WebInterface.GlobalNetIO;
import com.eotg.WebUtils.WebConstants;
public class Galaxy 
{
    //Basic Galaxy Stuff
    public static Galaxy World;
//...
public God GOD;
//...
protected GlobalNetIO IO;
//...
protected void makeRMI(GlobalNetIO bondee)
    {
        System.setProperty("java.security.policy",GlobalNetIO.DIR+"bin/settings.policy");
        //System.setProperty("java.rmi.server.codebase", "file:/"+GlobalNetIO.DIR+"bin/");

        if (System.getSecurityManager() == null)
            System.setSecurityManager ( new RMISecurityManager() );
        try
        {
            Registry reg = LocateRegistry.createRegistry(WebConstants.PORT);
            reg.bind(WebConstants.SERVICE_NAME, bondee);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
//...
protected void makeRMI(GlobalNetIO bondee)
    {
        System.setProperty("java.security.policy",GlobalNetIO.DIR+"bin/settings.policy");
        //System.setProperty("java.rmi.server.codebase", "file:/"+GlobalNetIO.DIR+"bin/");

        if (System.getSecurityManager() == null)
            System.setSecurityManager ( new RMISecurityManager() );
        try
        {
            Registry reg = LocateRegistry.createRegistry(WebConstants.PORT);
            reg.bind(WebConstants.SERVICE_NAME, bondee);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

ClientIO:

package com.eotg.Client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import com.eotg.WebUtils.*;

public class ClientIO
{
    protected EotGRemote m_RemoteStream;
    protected String m_szClientID;
    public static String URL = "192.168.1.4";
    public static final String DIR = "c:/Users/Josh/Dropbox/EotG/";

    public ClientIO()
    {
        System.setProperty("java.rmi.server.codebase", "file:/"+DIR+"/Eo_Nova_Server/bin/");
        System.setProperty("java.security.policy", DIR+"/Eo_Nova_Client/bin/settings.policy");
        if (System.getSecurityManager() == null)
        {
            System.setSecurityManager(new RMISecurityManager());
        }
        System.out.println("Enter the Server IP adress (The IP adress of the machine that the server is running on)");
        try 
        {
            ClientIO.URL = new BufferedReader(new InputStreamReader(System.in)).readLine();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        /*try {
            URL = java.net.InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }*/
        Connect();
    }

    public EotGRemote getRemoteStream()
    {
        return m_RemoteStream;
    }

    public String getClientID()
    {
        return m_szClientID;
    }

    public String getServerMessage()
    {
        try 
        {
            Registry registry = LocateRegistry.getRegistry(URL, WebConstants.PORT);
            //different physical machines, this might have to change
            m_RemoteStream = (EotGRemote) registry.lookup(WebConstants.SERVICE_NAME);
        }
        catch (RemoteException | NotBoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "";
    }
//...
public void registerAccount(String szUsername, String szFirstName, String szLastName, String szEmail)
    {
        try{
            String[] psz = getRemoteStream().registerAccount(szUsername, szFirstName, szLastName, szEmail);
        boolean bSuccess = psz[0].equals("1");
        if (bSuccess)
            GUI.Global.destroyRegisterBox();
        }
        catch (RemoteException e)
        {
            e.printStackTrace();
        }
    }

The EotGRemote interface, which extends remote and is implemented by GlobalNetIO.

package com.eotg.WebUtils;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface EotGRemote extends Remote 
{
    //Basic methods
    public void logout(String szID) throws RemoteException;

    //User-specific methods
    public String[] login(String szUsername, String szPassword) throws RemoteException;
    public String[] getUserAttribute(String szID, int iAttribute) throws RemoteException;
    public String[] tryChangeUserAttribute(String szID, int iAttribute, String szNewVal) throws RemoteException;

    //Global Context Methods
    public int getNumRaceInfos() throws RemoteException;
    public int getNumFactionInfos() throws RemoteException;
    public String[] registerAccount(String szUsername, String szFirstName, String szLastName, String szEmail) throws RemoteException;

}

Am I right? And regardless, can anyone point me towards fixing this error?

1

There are 1 answers

1
user207421 On

public class GlobalNetIO implements EotGRemote, Serializable

Make that

public class GlobalNetIO extends UnicastRemoteObject implements EotGRemote

throwing Serializable away, and add throws RemoteException to its constructor.

At present GlobalNetIO isn't a remote object at all, it is what I would call a mobile agent. It is serialized to the Registry, and again to the client when it does the lookup, and executes there.