Я пытаюсь вернуть нормальный класс через вызов RMI. На моем сервере хранится экземпляр класса GameState, над которым я хочу выполнять действия с помощью его методов из клиентского приложения. Таким образом, RMI отлично работает, если просто вернуть целое число или что-то в этом роде, но при попытке вернуть GameState, который является классом, определенным внутри java-файла GameServer, возникает следующая ошибка (состояние игры не объявляется ни общедоступным, ни защищенным, ни закрытым):
Исключение в потоке "main" java.lang.IllegalAccessError: попытка доступа к классу GameState из класса $Proxy0 в $Proxy0.getGameState(неизвестный источник) в GameClient.login(GameClient.java:204) в GameClient.main(GameClient.java: 168)
Итак, я предполагаю, что клиентское приложение знает, как выглядит GameState, но не имеет к нему доступа?
Я попытался сделать GameState общедоступным классом в своем собственном файле, но тогда различные подключающиеся клиентские приложения получают каждое свое собственное GameState, поэтому похоже, что оно не получает его с сервера.
Вот код, который я считаю актуальным:
Удаленный интерфейс:
import java.rmi.*;
public interface ServerInterface extends Remote
{
public GameState getGameState() throws RemoteException;
}
Некоторые, если код сервера:
public class GameServer extends UnicastRemoteObject implements ServerInterface {
/**
*
*/
private static final long serialVersionUID = -6633456258968168102L;
private final static int DEFAULT_NAMING_PORT = 9955; // TODO: IMPORTANT - change this to a group-specific number,
// e.g., 2000 + group number. The number should be the same
// as in GameClient.java.
private final GameState m_state;
public static void main(String[] args) {
//the variables: port and host etc it configurated here, but has nothing to do with the RMI problem.
try {
GameServer instance = new GameServer(players);
System.out.print("Setting up registry on "+host+":"+port+" ... ");
//Set up an unrestricted security manager.
if (System.getSecurityManager() == null) {
// Set security manager to an instance of a dynamically created
// subclass of RMISecurityManager with the checkPermission() method overloaded
System.setSecurityManager(
new RMISecurityManager() {
@Override
public void checkPermission(Permission permission) {
}
}
);
}
// Create a registry for binding names (name server)
Registry naming = LocateRegistry.createRegistry(port);
System.out.println("done.");
String rmiObjectName = "GeschenktServer";
System.out.print("Binding name "+rmiObjectName+" ... ");
naming.rebind(rmiObjectName, instance);
System.out.println("done.");
} catch(RemoteException e) {
System.err.println("Could not start server: "+e);
System.exit(-1);
}
}
//the rest of the server code....
//the GameState declared in the same file
class GameState implements java.io.Serializable {
private static final long serialVersionUID = 545671487061859760L;
//the rest of the Game state code.
Вот часть клиентского кода:
private void login() {
try {
System.out.println("Connecting to server on host "+m_host+".");
// Set up an unrestricted security manager. In the server we trust.
// See GameServer.java for code explanation.
if (System.getSecurityManager() == null) {
System.setSecurityManager(
new RMISecurityManager() {
@Override
public void checkPermission(Permission permission) {
}
}
);
}
System.out.print("Locating registry on "+m_host+":"+m_port+" ... ");
Registry naming = LocateRegistry.getRegistry(m_host, m_port);
System.out.println("done.");
String name = "GeschenktServer";
System.out.print("Looking up name "+name+" ... ");
m_server = (ServerInterface) naming.lookup(name);
System.out.println("done.");
// TODO: Connect the player, i.e., register the player with the server.
// Make sure that the player cannot register if there are already enough players.
m_Id = m_server.getGameState().loginPlayer(m_name); //this line is causing the error...
if(m_Id < 0)
System.exit(0);
System.out.println("Server connection successful.");
m_window = new GameWindow(m_server, m_name, m_Id);
m_window.run();
} catch (Exception e) {
System.out.println("Connection failed - "+e);
System.exit(1);
}
}
}
Я использую eclipse, чтобы делать все это, и, основываясь на том, что у меня есть красное мнение о RMI в eclipse, rmic и другие вещи больше не нужны, я прав?
Итак, у кого-нибудь есть идеи?
Заранее спасибо!