我正在尝试使用RMI实施2人网络问答游戏。我有一个DispatcherInterface
(接口)和Dispatcher
(为前者实现),它们尊重RMI体系结构。
服务器模型具有User
和Theme
,其中Quiz
将处于特定主题,我的想法是,当User
连接到Theme
时,它们d被添加到Map<User,Theme> waitingList
中,直到出现另一个User
与他们对抗。
我的问题出在实现上,而尝试实现一个简单的setter方法来将用户添加到等待列表时,出现以下错误:
Error occurred in server thread; nested exception is:
java.lang.NoClassDefFoundError: java/sql/SQLException
这对我来说没有意义,因为我的类路径已为RMI注册表和编译/运行命令很好地定义。
public interface DispatcherInterface extends Remote {
public User login(ReceiverInterface client, String email, String password) throws RemoteException;
public void addToWaitingList(int userID, Theme theme) throws RemoteException;
public void addToWaitingList(User user, Theme theme) throws RemoteException;
}
第一种方法可以完美地工作,而另一种方法则不管其实现方式如何(尝试了简单的System.out.print("test")
),但是我发现它很不方便,因为我必须遍历连接的用户列表。为了获得User
实例,我需要添加到waitingList
中。因此,理想情况下,我希望能够将User
的实例传递给该方法。
public class User implements Serializable {
public ReceiverInterface client;
public int id;
public String pseudo;
...
}
我不明白为什么不能将User
对象传递给方法,尤其是因为它是可序列化的。
出于完整性考虑,对于客户端部分,我类似地实现了ReceiverInterface
和Receiver
,它们通过代理(DispatcherInterface)与服务器进行通信
public class Receiver implements ReceiverInterface {
private DispatcherInterface = proxy;
private User user;
private String serverIP;
public Receiver(String serverIP) throws RemoteException, NotBoundException {
this.serverIP = serverIP;
Registry registry = LocateRegistry.getRegistry(serverIP);
this.proxy = (DispatcherInterface) registry.lookup("QuizApp");
}
...
}
感谢您的帮助。
编辑: 我使用IDE(IntelliJ)运行我的代码,它使用以下命令:
/usr/lib/jvm/java-10-openjdk/bin/java -javaagent:/opt/intellij-idea-ultimate-edition/lib/idea_rt.jar=41683:/opt/intellij-idea-ultimate-edition/bin -Dfile.encoding=UTF-8 -classpath /home/rand/gm4/JAVA/QuizApp/out/production/QuizApp:/home/rand/gm4/JAVA/QuizApp/lib/miglayout-swing-5.2.jar:/home/rand/gm4/JAVA/QuizApp/lib/miglayout-core-5.2.jar:/home/rand/gm4/JAVA/QuizApp/lib/sqlite-jdbc-3.23.1.jar server.Run
从条件上讲,哪个条件更好(没有.jar
依赖项)是
javac -d out/production/[project_name] src/server/Run.java
javac -d out/production/[project_name] src/client/Run.java
rmiregistry -J-Djava.class.path=out/production/[project_name]/
java -cp out/production/[project_name] server.Run
java -cp out/production/[project_name] client.Run
答案 0 :(得分:0)
您正在使用jdk 10执行代码。在jdk 9中,某些代码库已移入模块,并且默认情况下不再可用,java.sql在这些非根模块之一中。您需要在Java命令中使用“ --add-modules java.sql”,以使java.sql包在运行时可用。
由于您使用的是intellij来运行代码,因此以下文档可能有助于解释从ide运行时如何设置intellij使其包含此模块。 https://www.jetbrains.com/help/idea/getting-started-with-java-9-module-system.html